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

Side by Side Diff: chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc

Issue 2534023002: Create a DataUseRecorder instance for each page load in Chrome. (Closed)
Patch Set: Remove debug logs Created 4 years 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 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>
8
7 #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"
8 #include "components/data_use_measurement/content/content_url_request_classifier .h" 11 #include "components/data_use_measurement/content/content_url_request_classifier .h"
9 #include "components/data_use_measurement/core/data_use_recorder.h" 12 #include "components/data_use_measurement/core/data_use_recorder.h"
10 #include "components/data_use_measurement/core/data_use_user_data.h" 13 #include "components/data_use_measurement/core/data_use_user_data.h"
11 #include "components/data_use_measurement/core/url_request_classifier.h" 14 #include "components/data_use_measurement/core/url_request_classifier.h"
12 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/navigation_handle.h" 16 #include "content/public/browser/navigation_handle.h"
14 #include "content/public/browser/render_frame_host.h" 17 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/resource_request_info.h" 18 #include "content/public/browser/resource_request_info.h"
16 #include "content/public/common/browser_side_navigation_policy.h" 19 #include "content/public/common/browser_side_navigation_policy.h"
20 #include "ipc/ipc_message.h"
17 #include "net/url_request/url_request.h" 21 #include "net/url_request/url_request.h"
18 22
19 namespace data_use_measurement { 23 namespace data_use_measurement {
20 24
21 // static 25 // static
22 const void* ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: 26 const void* ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::
23 kUserDataKey = static_cast<void*>( 27 kUserDataKey = static_cast<void*>(
24 &ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::kUserDataKey); 28 &ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::kUserDataKey);
25 29
26 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: 30 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::
27 DataUseRecorderEntryAsUserData(DataUseRecorderEntry entry) 31 DataUseRecorderEntryAsUserData(DataUseRecorderEntry entry)
28 : entry_(entry) {} 32 : entry_(entry) {}
29 33
30 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData:: 34 ChromeDataUseAscriber::DataUseRecorderEntryAsUserData::
31 ~DataUseRecorderEntryAsUserData() {} 35 ~DataUseRecorderEntryAsUserData() {}
32 36
33 ChromeDataUseAscriber::ChromeDataUseAscriber() { 37 ChromeDataUseAscriber::ChromeDataUseAscriber() {
34 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 38 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
35 } 39 }
36 40
37 ChromeDataUseAscriber::~ChromeDataUseAscriber() { 41 ChromeDataUseAscriber::~ChromeDataUseAscriber() {
38 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 42 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
39 DCHECK_EQ(0u, data_use_recorders_.size()); 43 DCHECK_EQ(0u, data_use_recorders_.size());
40 } 44 }
41 45
42 DataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder( 46 ChromeDataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder(
43 net::URLRequest* request) { 47 net::URLRequest* request,
48 bool can_create_new) {
49 DataUseRecorderEntry entry = GetDataUseRecorderEntry(request, can_create_new);
50 return entry == data_use_recorders_.end() ? nullptr : (*entry).get();
RyanSturm 2016/11/29 20:32:59 nit: s/(*entry)./entry->/ I'm not totally sure tha
Not at Google. Contact bengr 2016/11/30 00:21:15 Not applicable since avoiding unique_ptr.
51 }
52
53 ChromeDataUseAscriber::DataUseRecorderEntry
54 ChromeDataUseAscriber::GetDataUseRecorderEntry(net::URLRequest* request,
55 bool can_create_new) {
44 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 56 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
45 return nullptr; 57
58 // TODO(ryansturm): Handle PlzNavigate (http://crbug/664233).
59 if (content::IsBrowserSideNavigationEnabled())
60 return data_use_recorders_.end();
61
62 // If a DataUseRecorder has already been set as user data, then return that.
63 auto user_data = static_cast<DataUseRecorderEntryAsUserData*>(
64 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey));
65 if (user_data)
66 return user_data->recorder_entry();
67
68 if (!can_create_new)
69 return data_use_recorders_.end();
70
71 // If request is associated with a ChromeService, create a new
72 // DataUseRecorder for it. There is no reason to aggregate URLRequests
73 // from ChromeServices into the same DataUseRecorder instance.
74 DataUseUserData* service = static_cast<DataUseUserData*>(
75 request->GetUserData(DataUseUserData::kUserDataKey));
76 if (service) {
77 DataUseRecorderEntry entry = CreateNewDataUseRecorder(request);
78
79 (*entry)->data_use().set_description(
RyanSturm 2016/11/29 20:32:59 nit: This is a little difficult to read. Maybe ent
Not at Google. Contact bengr 2016/11/30 00:21:15 Done
80 DataUseUserData::GetServiceNameAsString(service->service_name()));
81 return entry;
82 }
83
84 int render_process_id = -1;
85 int render_frame_id = -1;
86 bool has_valid_frame = content::ResourceRequestInfo::GetRenderFrameForRequest(
87 request, &render_process_id, &render_frame_id);
88 if (has_valid_frame &&
89 render_frame_id != SpecialRoutingIDs::MSG_ROUTING_NONE) {
90 DCHECK(render_process_id >= 0 || render_frame_id >= 0);
91
92 // Browser tests may not set up DataUseWebContentsObservers in which case
93 // this class never sees navigation and frame events so DataUseRecorders
94 // will never be destroyed. To avoid this, we ignore requests whose
95 // render frames don't have a record. However, this can also be caused by
96 // URLRequests racing the frame create events.
97 // TODO(kundaji): Add UMA.
98 RenderFrameHostID frame_key(render_process_id, render_frame_id);
99 auto frame_iter = render_frame_data_use_map_.find(frame_key);
100 if (frame_iter == render_frame_data_use_map_.end()) {
101 return data_use_recorders_.end();
102 }
103
104 const content::ResourceRequestInfo* request_info =
105 content::ResourceRequestInfo::ForRequest(request);
106 content::ResourceType resource_type =
107 request_info ? request_info->GetResourceType()
108 : content::RESOURCE_TYPE_LAST_TYPE;
109
110 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
111 content::GlobalRequestID navigation_key =
112 request_info->GetGlobalRequestID();
113
114 DataUseRecorderEntry new_entry = CreateNewDataUseRecorder(request);
115 (*new_entry)->set_main_frame_request_id(navigation_key);
116 pending_navigation_data_use_map_.insert(
117 std::make_pair(navigation_key, new_entry));
118
119 return new_entry;
120 }
121
122 DCHECK(frame_iter != render_frame_data_use_map_.end());
123 auto entry = frame_iter->second;
124 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey,
125 new DataUseRecorderEntryAsUserData(entry));
126 (*entry)->AddPendingURLRequest(request);
127 return entry;
128 }
129
130 // Create a new DataUseRecorder for all other requests.
131 DataUseRecorderEntry entry = CreateNewDataUseRecorder(request);
132 DataUse& data_use = (*entry)->data_use();
133 data_use.set_url(request->url());
134 return entry;
46 } 135 }
47 136
48 void ChromeDataUseAscriber::OnBeforeUrlRequest(net::URLRequest* request) { 137 void ChromeDataUseAscriber::OnBeforeUrlRequest(net::URLRequest* request) {
49 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 138 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
139 DataUseAscriber::OnBeforeUrlRequest(request);
50 140
51 // TODO(kundaji): Handle PlzNavigate. 141 // TODO(kundaji): Handle PlzNavigate.
52 if (content::IsBrowserSideNavigationEnabled()) 142 if (content::IsBrowserSideNavigationEnabled())
53 return; 143 return;
54 144
55 auto service = static_cast<DataUseUserData*>( 145 auto service = static_cast<DataUseUserData*>(
56 request->GetUserData(DataUseUserData::kUserDataKey)); 146 request->GetUserData(DataUseUserData::kUserDataKey));
57 if (service) 147 if (service)
58 return; 148 return;
59 149
(...skipping 24 matching lines...) Expand all
84 return; 174 return;
85 } 175 }
86 176
87 // If this request is already being tracked, do not create a new entry. 177 // If this request is already being tracked, do not create a new entry.
88 auto user_data = static_cast<DataUseRecorderEntryAsUserData*>( 178 auto user_data = static_cast<DataUseRecorderEntryAsUserData*>(
89 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); 179 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey));
90 if (user_data) 180 if (user_data)
91 return; 181 return;
92 182
93 DataUseRecorderEntry entry = data_use_recorders_.insert( 183 DataUseRecorderEntry entry = data_use_recorders_.insert(
94 data_use_recorders_.end(), base::MakeUnique<DataUseRecorder>()); 184 data_use_recorders_.end(), base::MakeUnique<ChromeDataUseRecorder>());
95 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey, 185 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey,
96 new DataUseRecorderEntryAsUserData(entry)); 186 new DataUseRecorderEntryAsUserData(entry));
97 pending_navigation_data_use_map_.insert( 187 pending_navigation_data_use_map_.insert(
98 std::make_pair(request_info->GetGlobalRequestID(), entry)); 188 std::make_pair(request_info->GetGlobalRequestID(), entry));
99 } 189 }
100 190
101 void ChromeDataUseAscriber::OnUrlRequestDestroyed(net::URLRequest* request) { 191 void ChromeDataUseAscriber::OnUrlRequestDestroyed(net::URLRequest* request) {
192 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
193
194 DataUseRecorderEntry entry = GetDataUseRecorderEntry(request, true);
195
196 if (entry == data_use_recorders_.end())
197 return;
198
199 DataUseRecorder* recorder = (*entry).get();
200
201 RenderFrameHostID frame_key = (*entry)->main_frame_id();
202 auto frame_iter = render_frame_data_use_map_.find(frame_key);
203 bool is_in_render_frame_map =
204 frame_iter != render_frame_data_use_map_.end() &&
205 (*frame_iter->second)->HasPendingURLRequest(request);
206
102 const content::ResourceRequestInfo* request_info = 207 const content::ResourceRequestInfo* request_info =
103 content::ResourceRequestInfo::ForRequest(request); 208 content::ResourceRequestInfo::ForRequest(request);
104 content::ResourceType resource_type = request_info 209 content::ResourceType resource_type = request_info
105 ? request_info->GetResourceType() 210 ? request_info->GetResourceType()
106 : content::RESOURCE_TYPE_LAST_TYPE; 211 : content::RESOURCE_TYPE_LAST_TYPE;
107 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { 212
108 // If request was not successful, then ReadyToCommitNavigation will not be 213 bool is_in_pending_navigation_map = false;
109 // called. So delete the pending navigation DataUseRecorderEntry here. 214 if (request_info && resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
110 if (!request->status().is_success()) { 215 auto navigation_iter = pending_navigation_data_use_map_.find(
111 DeletePendingNavigationEntry(request_info->GetGlobalRequestID()); 216 (*entry)->main_frame_request_id());
217 is_in_pending_navigation_map =
218 navigation_iter != pending_navigation_data_use_map_.end();
219
220 // If request was not successful, then NavigationHandle in
221 // DidFinishMainFrameNavigation will not have GlobalRequestID. So we erase
222 // the DataUseRecorderEntry here.
223 if (is_in_pending_navigation_map && !request->status().is_success()) {
224 pending_navigation_data_use_map_.erase(navigation_iter);
225 is_in_pending_navigation_map = false;
112 } 226 }
113 } 227 }
228
229 DataUseAscriber::OnUrlRequestDestroyed(request);
230 request->RemoveUserData(DataUseRecorderEntryAsUserData::kUserDataKey);
231
232 if (recorder->IsDataUseComplete() && !is_in_render_frame_map &&
233 !is_in_pending_navigation_map) {
234 OnDataUseCompleted(entry);
235 data_use_recorders_.erase(entry);
236 }
114 } 237 }
115 238
116 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id, 239 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id,
117 int render_frame_id, 240 int render_frame_id,
118 int parent_render_process_id, 241 int parent_render_process_id,
119 int parent_render_frame_id) { 242 int parent_render_frame_id) {
120 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 243 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
121 244
122 // TODO(kundaji): Point child render frames to the same DataUseRecorder as 245 if (parent_render_process_id != -1 && parent_render_frame_id != -1) {
123 // parent render frame. 246 // Create an entry in |render_frame_data_use_map_| for this frame with
124 DataUseRecorderEntry entry = data_use_recorders_.insert( 247 // the same DataUseRecorderEntry as its parent frame.
125 data_use_recorders_.end(), base::MakeUnique<DataUseRecorder>()); 248 auto frame_iter = render_frame_data_use_map_.find(
126 render_frame_data_use_map_.insert(std::make_pair( 249 RenderFrameHostID(parent_render_process_id, parent_render_frame_id));
127 RenderFrameHostID(render_process_id, render_frame_id), entry)); 250
251 DCHECK(frame_iter != render_frame_data_use_map_.end());
252
253 DataUseRecorderEntry entry = frame_iter->second;
254 render_frame_data_use_map_.insert(std::make_pair(
255 RenderFrameHostID(render_process_id, render_frame_id), entry));
256 } else {
257 auto frame_iter = render_frame_data_use_map_.find(
258 RenderFrameHostID(render_process_id, render_frame_id));
259 DCHECK(frame_iter == render_frame_data_use_map_.end());
260 DataUseRecorderEntry entry = CreateNewDataUseRecorder(nullptr);
261 (*entry)->set_main_frame_id(
262 RenderFrameHostID(render_process_id, render_frame_id));
263 render_frame_data_use_map_.insert(std::make_pair(
264 RenderFrameHostID(render_process_id, render_frame_id), entry));
265 }
128 } 266 }
129 267
130 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id, 268 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id,
131 int render_frame_id, 269 int render_frame_id,
132 int parent_render_process_id, 270 int parent_render_process_id,
133 int parent_render_frame_id) { 271 int parent_render_frame_id) {
134 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 272 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
273
135 RenderFrameHostID key(render_process_id, render_frame_id); 274 RenderFrameHostID key(render_process_id, render_frame_id);
136 auto frame_iter = render_frame_data_use_map_.find(key); 275 auto frame_iter = render_frame_data_use_map_.find(key);
276
137 DCHECK(frame_iter != render_frame_data_use_map_.end()); 277 DCHECK(frame_iter != render_frame_data_use_map_.end());
278
138 DataUseRecorderEntry entry = frame_iter->second; 279 DataUseRecorderEntry entry = frame_iter->second;
280 DataUseRecorder* recorder = (*entry).get();
281
282 if (parent_render_process_id == -1 && parent_render_frame_id == -1 &&
283 recorder->IsDataUseComplete()) {
284 OnDataUseCompleted(entry);
285 data_use_recorders_.erase(entry);
286 }
287
139 render_frame_data_use_map_.erase(frame_iter); 288 render_frame_data_use_map_.erase(frame_iter);
140
141 data_use_recorders_.erase(entry);
142 } 289 }
143 290
144 void ChromeDataUseAscriber::DidStartMainFrameNavigation( 291 void ChromeDataUseAscriber::DidStartMainFrameNavigation(
145 GURL gurl, 292 GURL gurl,
146 int render_process_id, 293 int render_process_id,
147 int render_frame_id, 294 int render_frame_id,
148 void* navigation_handle) { 295 void* navigation_handle) {
149 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 296 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
150 } 297 }
151 298
152 void ChromeDataUseAscriber::ReadyToCommitMainFrameNavigation( 299 void ChromeDataUseAscriber::ReadyToCommitMainFrameNavigation(
153 GURL gurl, 300 GURL gurl,
154 content::GlobalRequestID global_request_id, 301 content::GlobalRequestID global_request_id,
155 int render_process_id, 302 int render_process_id,
156 int render_frame_id, 303 int render_frame_id,
157 bool is_same_page_navigation, 304 bool is_same_page_navigation,
158 void* navigation_handle) { 305 void* navigation_handle) {
159 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 306 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
160 307
161 // TODO(kundaji): Move the DataUseRecorderEntry from pending navigation map 308 // Find the DataUseRecorderEntry the frame is associated with
162 // to render frame map if |is_same_page_navigation| is true. Otherwise, 309 auto frame_it = render_frame_data_use_map_.find(
163 // merge it with the DataUseRecorderEntry in the render frame map. 310 RenderFrameHostID(render_process_id, render_frame_id));
164 DeletePendingNavigationEntry(global_request_id); 311
312 // Find the pending navigation entry.
313 auto navigation_iter =
314 pending_navigation_data_use_map_.find(global_request_id);
315 // We might not find a navigation entry since the pending navigation may not
316 // have caused any HTTP or HTTPS URLRequests to be made.
317 if (navigation_iter == pending_navigation_data_use_map_.end()) {
318 // No pending navigation entry to worry about. However, the old frame entry
319 // must be removed from frame map, and possibly marked complete and deleted.
320 if (frame_it != render_frame_data_use_map_.end()) {
321 DataUseRecorderEntry old_frame_entry = frame_it->second;
322 render_frame_data_use_map_.erase(frame_it);
323 if ((*old_frame_entry)->IsDataUseComplete()) {
324 OnDataUseCompleted(old_frame_entry);
325 data_use_recorders_.erase(old_frame_entry);
326 }
327
328 // Add a new recorder to the render frame map to replace the deleted one.
329 DataUseRecorderEntry entry = data_use_recorders_.insert(
330 data_use_recorders_.end(), base::MakeUnique<ChromeDataUseRecorder>());
331 render_frame_data_use_map_.insert(std::make_pair(
332 RenderFrameHostID(render_process_id, render_frame_id), entry));
333 }
334 return;
335 }
336
337 DataUseRecorderEntry entry = navigation_iter->second;
338 pending_navigation_data_use_map_.erase(navigation_iter);
339 (*entry)->set_main_frame_id(
340 RenderFrameHostID(render_process_id, render_frame_id));
341
342 // If the frame has already been deleted then mark this navigation as having
343 // completed its data use.
344 if (frame_it == render_frame_data_use_map_.end()) {
345 if ((*entry)->IsDataUseComplete()) {
346 OnDataUseCompleted(entry);
347 data_use_recorders_.erase(entry);
348 }
349 return;
350 }
351 DataUseRecorderEntry old_frame_entry = frame_it->second;
352 if (is_same_page_navigation) {
353 (*old_frame_entry)->MergeFrom((*entry).get());
354
355 for (auto request : (*entry)->pending_url_requests()) {
356 request->RemoveUserData(DataUseRecorderEntryAsUserData::kUserDataKey);
357 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey,
358 new DataUseRecorderEntryAsUserData(old_frame_entry));
359 (*old_frame_entry)->AddPendingURLRequest(request);
360 }
361
362 (*entry)->RemoveAllPendingURLRequests();
363
364 data_use_recorders_.erase(entry);
365 } else {
366 // Navigation is not same page, so remove old entry from
367 // |render_frame_data_use_map_|, possibly marking it complete.
368 render_frame_data_use_map_.erase(frame_it);
369 if ((*old_frame_entry)->IsDataUseComplete()) {
370 OnDataUseCompleted(old_frame_entry);
371 data_use_recorders_.erase(old_frame_entry);
372 }
373
374 DataUse& data_use = (*entry)->data_use();
375
376 DCHECK(!data_use.url().is_valid() || data_use.url() == gurl)
377 << "is valid: " << data_use.url().is_valid()
378 << "; data_use.url(): " << data_use.url().spec()
379 << "; gurl: " << gurl.spec();
380 if (!data_use.url().is_valid()) {
381 data_use.set_url(gurl);
382 }
383
384 render_frame_data_use_map_.insert(std::make_pair(
385 RenderFrameHostID(render_process_id, render_frame_id), entry));
386 }
165 } 387 }
166 388
167 void ChromeDataUseAscriber::DidRedirectMainFrameNavigation( 389 void ChromeDataUseAscriber::OnDataUseCompleted(DataUseRecorderEntry entry) {
168 GURL gurl, 390 // TODO(ryansturm): Notify observers that data use is complete.
169 int render_process_id,
170 int render_frame_id,
171 void* navigation_handle) {
172 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
173 }
174
175 void ChromeDataUseAscriber::DeletePendingNavigationEntry(
176 content::GlobalRequestID global_request_id) {
177 auto navigation_iter =
178 pending_navigation_data_use_map_.find(global_request_id);
179 // Pending navigation entry will not be found if finish navigation
180 // raced the URLRequest.
181 if (navigation_iter != pending_navigation_data_use_map_.end()) {
182 auto entry = navigation_iter->second;
183 pending_navigation_data_use_map_.erase(navigation_iter);
184 data_use_recorders_.erase(entry);
185 }
186 } 391 }
187 392
188 std::unique_ptr<URLRequestClassifier> 393 std::unique_ptr<URLRequestClassifier>
189 ChromeDataUseAscriber::CreateURLRequestClassifier() const { 394 ChromeDataUseAscriber::CreateURLRequestClassifier() const {
190 return base::MakeUnique<ContentURLRequestClassifier>(); 395 return base::MakeUnique<ContentURLRequestClassifier>();
191 } 396 }
192 397
398 ChromeDataUseAscriber::DataUseRecorderEntry
399 ChromeDataUseAscriber::CreateNewDataUseRecorder(net::URLRequest* request) {
400 DataUseRecorderEntry entry = data_use_recorders_.insert(
401 data_use_recorders_.end(), base::MakeUnique<ChromeDataUseRecorder>());
402 if (request) {
403 (*entry)->AddPendingURLRequest(request);
404 request->SetUserData(DataUseRecorderEntryAsUserData::kUserDataKey,
405 new DataUseRecorderEntryAsUserData(entry));
406 }
407 return entry;
408 }
409
193 } // namespace data_use_measurement 410 } // namespace data_use_measurement
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698