| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/net/load_timing_observer.h" | 5 #include "chrome/browser/net/load_timing_observer.h" |
| 6 | 6 |
| 7 #include "base/time.h" | 7 #include "base/time.h" |
| 8 #include "chrome/browser/net/chrome_net_log.h" | 8 #include "chrome/browser/net/chrome_net_log.h" |
| 9 #include "content/public/common/resource_response.h" | 9 #include "content/public/common/resource_response.h" |
| 10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 LoadTimingObserver::URLRequestRecord* | 76 LoadTimingObserver::URLRequestRecord* |
| 77 LoadTimingObserver::GetURLRequestRecord(uint32 source_id) { | 77 LoadTimingObserver::GetURLRequestRecord(uint32 source_id) { |
| 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 79 | 79 |
| 80 URLRequestToRecordMap::iterator it = url_request_to_record_.find(source_id); | 80 URLRequestToRecordMap::iterator it = url_request_to_record_.find(source_id); |
| 81 if (it != url_request_to_record_.end()) | 81 if (it != url_request_to_record_.end()) |
| 82 return &it->second; | 82 return &it->second; |
| 83 return NULL; | 83 return NULL; |
| 84 } | 84 } |
| 85 | 85 |
| 86 void LoadTimingObserver::OnAddEntry(net::NetLog::EventType type, | 86 void LoadTimingObserver::OnAddEntry(const net::NetLog::Entry& entry) { |
| 87 const base::TimeTicks& time, | |
| 88 const net::NetLog::Source& source, | |
| 89 net::NetLog::EventPhase phase, | |
| 90 net::NetLog::EventParameters* params) { | |
| 91 // The events that the Observer is interested in only occur on the IO thread. | 87 // The events that the Observer is interested in only occur on the IO thread. |
| 92 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) | 88 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) |
| 93 return; | 89 return; |
| 94 if (source.type == net::NetLog::SOURCE_URL_REQUEST) | 90 if (entry.source().type == net::NetLog::SOURCE_URL_REQUEST) |
| 95 OnAddURLRequestEntry(type, time, source, phase, params); | 91 OnAddURLRequestEntry(entry); |
| 96 else if (source.type == net::NetLog::SOURCE_HTTP_STREAM_JOB) | 92 else if (entry.source().type == net::NetLog::SOURCE_HTTP_STREAM_JOB) |
| 97 OnAddHTTPStreamJobEntry(type, time, source, phase, params); | 93 OnAddHTTPStreamJobEntry(entry); |
| 98 else if (source.type == net::NetLog::SOURCE_CONNECT_JOB) | 94 else if (entry.source().type == net::NetLog::SOURCE_CONNECT_JOB) |
| 99 OnAddConnectJobEntry(type, time, source, phase, params); | 95 OnAddConnectJobEntry(entry); |
| 100 else if (source.type == net::NetLog::SOURCE_SOCKET) | 96 else if (entry.source().type == net::NetLog::SOURCE_SOCKET) |
| 101 OnAddSocketEntry(type, time, source, phase, params); | 97 OnAddSocketEntry(entry); |
| 102 } | 98 } |
| 103 | 99 |
| 104 // static | 100 // static |
| 105 void LoadTimingObserver::PopulateTimingInfo( | 101 void LoadTimingObserver::PopulateTimingInfo( |
| 106 net::URLRequest* request, | 102 net::URLRequest* request, |
| 107 content::ResourceResponse* response) { | 103 content::ResourceResponse* response) { |
| 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 109 if (!(request->load_flags() & net::LOAD_ENABLE_LOAD_TIMING)) | 105 if (!(request->load_flags() & net::LOAD_ENABLE_LOAD_TIMING)) |
| 110 return; | 106 return; |
| 111 | 107 |
| 112 ChromeNetLog* chrome_net_log = static_cast<ChromeNetLog*>( | 108 ChromeNetLog* chrome_net_log = static_cast<ChromeNetLog*>( |
| 113 request->net_log().net_log()); | 109 request->net_log().net_log()); |
| 114 if (chrome_net_log == NULL) | 110 if (chrome_net_log == NULL) |
| 115 return; | 111 return; |
| 116 | 112 |
| 117 uint32 source_id = request->net_log().source().id; | 113 uint32 source_id = request->net_log().source().id; |
| 118 LoadTimingObserver* observer = chrome_net_log->load_timing_observer(); | 114 LoadTimingObserver* observer = chrome_net_log->load_timing_observer(); |
| 119 LoadTimingObserver::URLRequestRecord* record = | 115 LoadTimingObserver::URLRequestRecord* record = |
| 120 observer->GetURLRequestRecord(source_id); | 116 observer->GetURLRequestRecord(source_id); |
| 121 if (record) { | 117 if (record) { |
| 122 response->connection_id = record->socket_log_id; | 118 response->connection_id = record->socket_log_id; |
| 123 response->connection_reused = record->socket_reused; | 119 response->connection_reused = record->socket_reused; |
| 124 response->load_timing = record->timing; | 120 response->load_timing = record->timing; |
| 125 } | 121 } |
| 126 } | 122 } |
| 127 | 123 |
| 128 void LoadTimingObserver::OnAddURLRequestEntry( | 124 void LoadTimingObserver::OnAddURLRequestEntry(const net::NetLog::Entry& entry) { |
| 129 net::NetLog::EventType type, | |
| 130 const base::TimeTicks& time, | |
| 131 const net::NetLog::Source& source, | |
| 132 net::NetLog::EventPhase phase, | |
| 133 net::NetLog::EventParameters* params) { | |
| 134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 135 | 126 |
| 136 bool is_begin = phase == net::NetLog::PHASE_BEGIN; | 127 bool is_begin = entry.phase() == net::NetLog::PHASE_BEGIN; |
| 137 bool is_end = phase == net::NetLog::PHASE_END; | 128 bool is_end = entry.phase() == net::NetLog::PHASE_END; |
| 138 | 129 |
| 139 if (type == net::NetLog::TYPE_URL_REQUEST_START_JOB) { | 130 if (entry.type() == net::NetLog::TYPE_URL_REQUEST_START_JOB) { |
| 140 if (is_begin) { | 131 if (is_begin) { |
| 141 // Only record timing for entries with corresponding flag. | 132 // Only record timing for entries with corresponding flag. |
| 142 int load_flags = | 133 int load_flags; |
| 143 static_cast<net::URLRequestStartEventParameters*>(params)-> | 134 scoped_ptr<Value> event_params(entry.ParametersToValue()); |
| 144 load_flags(); | 135 if (!net::StartEventLoadFlagsFromEventParams(event_params.get(), |
| 136 &load_flags)) { |
| 137 NOTREACHED(); |
| 138 return; |
| 139 } |
| 140 |
| 145 if (!(load_flags & net::LOAD_ENABLE_LOAD_TIMING)) | 141 if (!(load_flags & net::LOAD_ENABLE_LOAD_TIMING)) |
| 146 return; | 142 return; |
| 147 | 143 |
| 148 // Prevents us from passively growing the memory unbounded in case | 144 // Prevents us from passively growing the memory unbounded in case |
| 149 // something went wrong. Should not happen. | 145 // something went wrong. Should not happen. |
| 150 if (url_request_to_record_.size() > kMaxNumEntries) { | 146 if (url_request_to_record_.size() > kMaxNumEntries) { |
| 151 LOG(WARNING) << "The load timing observer url request count has grown " | 147 LOG(WARNING) << "The load timing observer url request count has grown " |
| 152 "larger than expected, resetting"; | 148 "larger than expected, resetting"; |
| 153 url_request_to_record_.clear(); | 149 url_request_to_record_.clear(); |
| 154 } | 150 } |
| 155 | 151 |
| 156 URLRequestRecord& record = url_request_to_record_[source.id]; | 152 URLRequestRecord& record = url_request_to_record_[entry.source().id]; |
| 157 record.base_ticks = time; | 153 base::TimeTicks now = GetCurrentTime(); |
| 154 record.base_ticks = now; |
| 158 record.timing = ResourceLoadTimingInfo(); | 155 record.timing = ResourceLoadTimingInfo(); |
| 159 record.timing.base_ticks = time; | 156 record.timing.base_ticks = now; |
| 160 record.timing.base_time = TimeTicksToTime(time); | 157 record.timing.base_time = TimeTicksToTime(now); |
| 161 } | 158 } |
| 162 return; | 159 return; |
| 163 } else if (type == net::NetLog::TYPE_REQUEST_ALIVE) { | 160 } else if (entry.type() == net::NetLog::TYPE_REQUEST_ALIVE) { |
| 164 // Cleanup records based on the TYPE_REQUEST_ALIVE entry. | 161 // Cleanup records based on the TYPE_REQUEST_ALIVE entry. |
| 165 if (is_end) | 162 if (is_end) |
| 166 url_request_to_record_.erase(source.id); | 163 url_request_to_record_.erase(entry.source().id); |
| 167 return; | 164 return; |
| 168 } | 165 } |
| 169 | 166 |
| 170 URLRequestRecord* record = GetURLRequestRecord(source.id); | 167 URLRequestRecord* record = GetURLRequestRecord(entry.source().id); |
| 171 if (!record) | 168 if (!record) |
| 172 return; | 169 return; |
| 173 | 170 |
| 174 ResourceLoadTimingInfo& timing = record->timing; | 171 ResourceLoadTimingInfo& timing = record->timing; |
| 175 | 172 |
| 176 switch (type) { | 173 switch (entry.type()) { |
| 177 case net::NetLog::TYPE_PROXY_SERVICE: | 174 case net::NetLog::TYPE_PROXY_SERVICE: |
| 178 if (is_begin) | 175 if (is_begin) |
| 179 timing.proxy_start = TimeTicksToOffset(time, record); | 176 timing.proxy_start = TimeTicksToOffset(GetCurrentTime(), record); |
| 180 else if (is_end) | 177 else if (is_end) |
| 181 timing.proxy_end = TimeTicksToOffset(time, record); | 178 timing.proxy_end = TimeTicksToOffset(GetCurrentTime(), record); |
| 182 break; | 179 break; |
| 183 case net::NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB: { | 180 case net::NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB: { |
| 184 uint32 http_stream_job_id = static_cast<net::NetLogSourceParameter*>( | 181 net::NetLog::Source http_stream_job_source; |
| 185 params)->value().id; | 182 scoped_ptr<Value> event_params(entry.ParametersToValue()); |
| 183 if (!net::NetLog::Source::FromEventParameters( |
| 184 event_params.get(), |
| 185 &http_stream_job_source)) { |
| 186 NOTREACHED(); |
| 187 return; |
| 188 } |
| 189 DCHECK_EQ(net::NetLog::SOURCE_HTTP_STREAM_JOB, |
| 190 http_stream_job_source.type); |
| 191 |
| 186 HTTPStreamJobToRecordMap::iterator it = | 192 HTTPStreamJobToRecordMap::iterator it = |
| 187 http_stream_job_to_record_.find(http_stream_job_id); | 193 http_stream_job_to_record_.find(http_stream_job_source.id); |
| 188 if (it == http_stream_job_to_record_.end()) | 194 if (it == http_stream_job_to_record_.end()) |
| 189 return; | 195 return; |
| 190 if (!it->second.connect_start.is_null()) { | 196 if (!it->second.connect_start.is_null()) { |
| 191 timing.connect_start = TimeTicksToOffset(it->second.connect_start, | 197 timing.connect_start = TimeTicksToOffset(it->second.connect_start, |
| 192 record); | 198 record); |
| 193 } | 199 } |
| 194 if (!it->second.connect_end.is_null()) | 200 if (!it->second.connect_end.is_null()) |
| 195 timing.connect_end = TimeTicksToOffset(it->second.connect_end, record); | 201 timing.connect_end = TimeTicksToOffset(it->second.connect_end, record); |
| 196 if (!it->second.dns_start.is_null()) | 202 if (!it->second.dns_start.is_null()) |
| 197 timing.dns_start = TimeTicksToOffset(it->second.dns_start, record); | 203 timing.dns_start = TimeTicksToOffset(it->second.dns_start, record); |
| 198 if (!it->second.dns_end.is_null()) | 204 if (!it->second.dns_end.is_null()) |
| 199 timing.dns_end = TimeTicksToOffset(it->second.dns_end, record); | 205 timing.dns_end = TimeTicksToOffset(it->second.dns_end, record); |
| 200 if (!it->second.ssl_start.is_null()) | 206 if (!it->second.ssl_start.is_null()) |
| 201 timing.ssl_start = TimeTicksToOffset(it->second.ssl_start, record); | 207 timing.ssl_start = TimeTicksToOffset(it->second.ssl_start, record); |
| 202 if (!it->second.ssl_end.is_null()) | 208 if (!it->second.ssl_end.is_null()) |
| 203 timing.ssl_end = TimeTicksToOffset(it->second.ssl_end, record); | 209 timing.ssl_end = TimeTicksToOffset(it->second.ssl_end, record); |
| 204 record->socket_reused = it->second.socket_reused; | 210 record->socket_reused = it->second.socket_reused; |
| 205 record->socket_log_id = it->second.socket_log_id; | 211 record->socket_log_id = it->second.socket_log_id; |
| 206 break; | 212 break; |
| 207 } | 213 } |
| 208 case net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST: | 214 case net::NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST: |
| 209 if (is_begin) | 215 if (is_begin) |
| 210 timing.send_start = TimeTicksToOffset(time, record); | 216 timing.send_start = TimeTicksToOffset(GetCurrentTime(), record); |
| 211 else if (is_end) | 217 else if (is_end) |
| 212 timing.send_end = TimeTicksToOffset(time, record); | 218 timing.send_end = TimeTicksToOffset(GetCurrentTime(), record); |
| 213 break; | 219 break; |
| 214 case net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS: | 220 case net::NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS: |
| 215 if (is_begin) | 221 if (is_begin) { |
| 216 timing.receive_headers_start = TimeTicksToOffset(time, record); | 222 timing.receive_headers_start = |
| 217 else if (is_end) | 223 TimeTicksToOffset(GetCurrentTime(), record); |
| 218 timing.receive_headers_end = TimeTicksToOffset(time, record); | 224 } else if (is_end) { |
| 225 timing.receive_headers_end = |
| 226 TimeTicksToOffset(GetCurrentTime(), record); |
| 227 } |
| 219 break; | 228 break; |
| 220 default: | 229 default: |
| 221 break; | 230 break; |
| 222 } | 231 } |
| 223 } | 232 } |
| 224 | 233 |
| 225 void LoadTimingObserver::OnAddHTTPStreamJobEntry( | 234 void LoadTimingObserver::OnAddHTTPStreamJobEntry( |
| 226 net::NetLog::EventType type, | 235 const net::NetLog::Entry& entry) { |
| 227 const base::TimeTicks& time, | |
| 228 const net::NetLog::Source& source, | |
| 229 net::NetLog::EventPhase phase, | |
| 230 net::NetLog::EventParameters* params) { | |
| 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 232 | 237 |
| 233 bool is_begin = phase == net::NetLog::PHASE_BEGIN; | 238 bool is_begin = entry.phase() == net::NetLog::PHASE_BEGIN; |
| 234 bool is_end = phase == net::NetLog::PHASE_END; | 239 bool is_end = entry.phase() == net::NetLog::PHASE_END; |
| 235 | 240 |
| 236 if (type == net::NetLog::TYPE_HTTP_STREAM_JOB) { | 241 if (entry.type() == net::NetLog::TYPE_HTTP_STREAM_JOB) { |
| 237 if (is_begin) { | 242 if (is_begin) { |
| 238 // Prevents us from passively growing the memory unbounded in | 243 // Prevents us from passively growing the memory unbounded in |
| 239 // case something went wrong. Should not happen. | 244 // case something went wrong. Should not happen. |
| 240 if (http_stream_job_to_record_.size() > kMaxNumEntries) { | 245 if (http_stream_job_to_record_.size() > kMaxNumEntries) { |
| 241 LOG(WARNING) << "The load timing observer http stream job count " | 246 LOG(WARNING) << "The load timing observer http stream job count " |
| 242 "has grown larger than expected, resetting"; | 247 "has grown larger than expected, resetting"; |
| 243 http_stream_job_to_record_.clear(); | 248 http_stream_job_to_record_.clear(); |
| 244 } | 249 } |
| 245 | 250 |
| 246 http_stream_job_to_record_.insert( | 251 http_stream_job_to_record_.insert( |
| 247 std::make_pair(source.id, HTTPStreamJobRecord())); | 252 std::make_pair(entry.source().id, HTTPStreamJobRecord())); |
| 248 } else if (is_end) { | 253 } else if (is_end) { |
| 249 http_stream_job_to_record_.erase(source.id); | 254 http_stream_job_to_record_.erase(entry.source().id); |
| 250 } | 255 } |
| 251 return; | 256 return; |
| 252 } | 257 } |
| 253 | 258 |
| 254 HTTPStreamJobToRecordMap::iterator it = | 259 HTTPStreamJobToRecordMap::iterator it = |
| 255 http_stream_job_to_record_.find(source.id); | 260 http_stream_job_to_record_.find(entry.source().id); |
| 256 if (it == http_stream_job_to_record_.end()) | 261 if (it == http_stream_job_to_record_.end()) |
| 257 return; | 262 return; |
| 258 | 263 |
| 259 switch (type) { | 264 switch (entry.type()) { |
| 260 case net::NetLog::TYPE_SOCKET_POOL: | 265 case net::NetLog::TYPE_SOCKET_POOL: |
| 261 if (is_begin) | 266 if (is_begin) |
| 262 it->second.connect_start = time; | 267 it->second.connect_start = GetCurrentTime(); |
| 263 else if (is_end) | 268 else if (is_end) |
| 264 it->second.connect_end = time; | 269 it->second.connect_end = GetCurrentTime(); |
| 265 break; | 270 break; |
| 266 case net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB: { | 271 case net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB: { |
| 267 uint32 connect_job_id = static_cast<net::NetLogSourceParameter*>( | 272 net::NetLog::Source connect_job_source; |
| 268 params)->value().id; | 273 scoped_ptr<Value> event_params(entry.ParametersToValue()); |
| 269 if (last_connect_job_id_ == connect_job_id && | 274 if (!net::NetLog::Source::FromEventParameters(event_params.get(), |
| 275 &connect_job_source)) { |
| 276 NOTREACHED(); |
| 277 return; |
| 278 } |
| 279 DCHECK_EQ(net::NetLog::SOURCE_CONNECT_JOB, connect_job_source.type); |
| 280 |
| 281 if (last_connect_job_id_ == connect_job_source.id && |
| 270 !last_connect_job_record_.dns_start.is_null()) { | 282 !last_connect_job_record_.dns_start.is_null()) { |
| 271 it->second.dns_start = last_connect_job_record_.dns_start; | 283 it->second.dns_start = last_connect_job_record_.dns_start; |
| 272 it->second.dns_end = last_connect_job_record_.dns_end; | 284 it->second.dns_end = last_connect_job_record_.dns_end; |
| 273 } | 285 } |
| 274 break; | 286 break; |
| 275 } | 287 } |
| 276 case net::NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET: | 288 case net::NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET: |
| 277 it->second.socket_reused = true; | 289 it->second.socket_reused = true; |
| 278 break; | 290 break; |
| 279 case net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET: | 291 case net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET: { |
| 280 it->second.socket_log_id = static_cast<net::NetLogSourceParameter*>( | 292 net::NetLog::Source socket_source; |
| 281 params)->value().id; | 293 scoped_ptr<Value> event_params(entry.ParametersToValue()); |
| 294 if (!net::NetLog::Source::FromEventParameters(event_params.get(), |
| 295 &socket_source)) { |
| 296 NOTREACHED(); |
| 297 return; |
| 298 } |
| 299 DCHECK_EQ(net::NetLog::SOURCE_SOCKET, socket_source.type); |
| 300 |
| 301 it->second.socket_log_id = socket_source.id; |
| 282 if (!it->second.socket_reused) { | 302 if (!it->second.socket_reused) { |
| 283 SocketToRecordMap::iterator socket_it = | 303 SocketToRecordMap::iterator socket_it = |
| 284 socket_to_record_.find(it->second.socket_log_id); | 304 socket_to_record_.find(it->second.socket_log_id); |
| 285 if (socket_it != socket_to_record_.end() && | 305 if (socket_it != socket_to_record_.end() && |
| 286 !socket_it->second.ssl_start.is_null()) { | 306 !socket_it->second.ssl_start.is_null()) { |
| 287 it->second.ssl_start = socket_it->second.ssl_start; | 307 it->second.ssl_start = socket_it->second.ssl_start; |
| 288 it->second.ssl_end = socket_it->second.ssl_end; | 308 it->second.ssl_end = socket_it->second.ssl_end; |
| 289 } | 309 } |
| 290 } | 310 } |
| 291 break; | 311 break; |
| 312 } |
| 292 default: | 313 default: |
| 293 break; | 314 break; |
| 294 } | 315 } |
| 295 } | 316 } |
| 296 | 317 |
| 297 void LoadTimingObserver::OnAddConnectJobEntry( | 318 void LoadTimingObserver::OnAddConnectJobEntry(const net::NetLog::Entry& entry) { |
| 298 net::NetLog::EventType type, | |
| 299 const base::TimeTicks& time, | |
| 300 const net::NetLog::Source& source, | |
| 301 net::NetLog::EventPhase phase, | |
| 302 net::NetLog::EventParameters* params) { | |
| 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 304 | 320 |
| 305 bool is_begin = phase == net::NetLog::PHASE_BEGIN; | 321 bool is_begin = entry.phase() == net::NetLog::PHASE_BEGIN; |
| 306 bool is_end = phase == net::NetLog::PHASE_END; | 322 bool is_end = entry.phase() == net::NetLog::PHASE_END; |
| 307 | 323 |
| 308 // Manage record lifetime based on the SOCKET_POOL_CONNECT_JOB entry. | 324 // Manage record lifetime based on the SOCKET_POOL_CONNECT_JOB entry. |
| 309 if (type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB) { | 325 if (entry.type() == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB) { |
| 310 if (is_begin) { | 326 if (is_begin) { |
| 311 // Prevents us from passively growing the memory unbounded in case | 327 // Prevents us from passively growing the memory unbounded in case |
| 312 // something went wrong. Should not happen. | 328 // something went wrong. Should not happen. |
| 313 if (connect_job_to_record_.size() > kMaxNumEntries) { | 329 if (connect_job_to_record_.size() > kMaxNumEntries) { |
| 314 LOG(WARNING) << "The load timing observer connect job count has grown " | 330 LOG(WARNING) << "The load timing observer connect job count has grown " |
| 315 "larger than expected, resetting"; | 331 "larger than expected, resetting"; |
| 316 connect_job_to_record_.clear(); | 332 connect_job_to_record_.clear(); |
| 317 } | 333 } |
| 318 | 334 |
| 319 connect_job_to_record_.insert( | 335 connect_job_to_record_.insert( |
| 320 std::make_pair(source.id, ConnectJobRecord())); | 336 std::make_pair(entry.source().id, ConnectJobRecord())); |
| 321 } else if (is_end) { | 337 } else if (is_end) { |
| 322 ConnectJobToRecordMap::iterator it = | 338 ConnectJobToRecordMap::iterator it = |
| 323 connect_job_to_record_.find(source.id); | 339 connect_job_to_record_.find(entry.source().id); |
| 324 if (it != connect_job_to_record_.end()) { | 340 if (it != connect_job_to_record_.end()) { |
| 325 last_connect_job_id_ = it->first; | 341 last_connect_job_id_ = it->first; |
| 326 last_connect_job_record_ = it->second; | 342 last_connect_job_record_ = it->second; |
| 327 connect_job_to_record_.erase(it); | 343 connect_job_to_record_.erase(it); |
| 328 } | 344 } |
| 329 } | 345 } |
| 330 } else if (type == net::NetLog::TYPE_HOST_RESOLVER_IMPL) { | 346 } else if (entry.type() == net::NetLog::TYPE_HOST_RESOLVER_IMPL) { |
| 331 ConnectJobToRecordMap::iterator it = | 347 ConnectJobToRecordMap::iterator it = |
| 332 connect_job_to_record_.find(source.id); | 348 connect_job_to_record_.find(entry.source().id); |
| 333 if (it != connect_job_to_record_.end()) { | 349 if (it != connect_job_to_record_.end()) { |
| 334 if (is_begin) | 350 if (is_begin) |
| 335 it->second.dns_start = time; | 351 it->second.dns_start = GetCurrentTime(); |
| 336 else if (is_end) | 352 else if (is_end) |
| 337 it->second.dns_end = time; | 353 it->second.dns_end = GetCurrentTime(); |
| 338 } | 354 } |
| 339 } | 355 } |
| 340 } | 356 } |
| 341 | 357 |
| 342 void LoadTimingObserver::OnAddSocketEntry( | 358 void LoadTimingObserver::OnAddSocketEntry(const net::NetLog::Entry& entry) { |
| 343 net::NetLog::EventType type, | |
| 344 const base::TimeTicks& time, | |
| 345 const net::NetLog::Source& source, | |
| 346 net::NetLog::EventPhase phase, | |
| 347 net::NetLog::EventParameters* params) { | |
| 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 349 | 360 |
| 350 bool is_begin = phase == net::NetLog::PHASE_BEGIN; | 361 bool is_begin = entry.phase() == net::NetLog::PHASE_BEGIN; |
| 351 bool is_end = phase == net::NetLog::PHASE_END; | 362 bool is_end = entry.phase() == net::NetLog::PHASE_END; |
| 352 | 363 |
| 353 // Manage record lifetime based on the SOCKET_ALIVE entry. | 364 // Manage record lifetime based on the SOCKET_ALIVE entry. |
| 354 if (type == net::NetLog::TYPE_SOCKET_ALIVE) { | 365 if (entry.type() == net::NetLog::TYPE_SOCKET_ALIVE) { |
| 355 if (is_begin) { | 366 if (is_begin) { |
| 356 // Prevents us from passively growing the memory unbounded in case | 367 // Prevents us from passively growing the memory unbounded in case |
| 357 // something went wrong. Should not happen. | 368 // something went wrong. Should not happen. |
| 358 if (socket_to_record_.size() > kMaxNumEntries) { | 369 if (socket_to_record_.size() > kMaxNumEntries) { |
| 359 LOG(WARNING) << "The load timing observer socket count has grown " | 370 LOG(WARNING) << "The load timing observer socket count has grown " |
| 360 "larger than expected, resetting"; | 371 "larger than expected, resetting"; |
| 361 socket_to_record_.clear(); | 372 socket_to_record_.clear(); |
| 362 } | 373 } |
| 363 | 374 |
| 364 socket_to_record_.insert( | 375 socket_to_record_.insert( |
| 365 std::make_pair(source.id, SocketRecord())); | 376 std::make_pair(entry.source().id, SocketRecord())); |
| 366 } else if (is_end) { | 377 } else if (is_end) { |
| 367 socket_to_record_.erase(source.id); | 378 socket_to_record_.erase(entry.source().id); |
| 368 } | 379 } |
| 369 return; | 380 return; |
| 370 } | 381 } |
| 371 SocketToRecordMap::iterator it = socket_to_record_.find(source.id); | 382 SocketToRecordMap::iterator it = socket_to_record_.find(entry.source().id); |
| 372 if (it == socket_to_record_.end()) | 383 if (it == socket_to_record_.end()) |
| 373 return; | 384 return; |
| 374 | 385 |
| 375 if (type == net::NetLog::TYPE_SSL_CONNECT) { | 386 if (entry.type() == net::NetLog::TYPE_SSL_CONNECT) { |
| 376 if (is_begin) | 387 if (is_begin) |
| 377 it->second.ssl_start = time; | 388 it->second.ssl_start = GetCurrentTime(); |
| 378 else if (is_end) | 389 else if (is_end) |
| 379 it->second.ssl_end = time; | 390 it->second.ssl_end = GetCurrentTime(); |
| 380 } | 391 } |
| 381 } | 392 } |
| 393 |
| 394 base::TimeTicks LoadTimingObserver::GetCurrentTime() const { |
| 395 return base::TimeTicks::Now(); |
| 396 } |
| OLD | NEW |