| 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/renderer/loadtimes_extension_bindings.h" | 5 #include "chrome/renderer/loadtimes_extension_bindings.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "content/public/renderer/document_state.h" | 10 #include "content/public/renderer/document_state.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 return kTransitionForwardBack; | 91 return kTransitionForwardBack; |
| 92 case blink::WebNavigationTypeReload: | 92 case blink::WebNavigationTypeReload: |
| 93 return kTransitionReload; | 93 return kTransitionReload; |
| 94 case blink::WebNavigationTypeOther: | 94 case blink::WebNavigationTypeOther: |
| 95 return kTransitionOther; | 95 return kTransitionOther; |
| 96 } | 96 } |
| 97 return kTransitionOther; | 97 return kTransitionOther; |
| 98 } | 98 } |
| 99 | 99 |
| 100 static void GetLoadTimes(const v8::FunctionCallbackInfo<v8::Value>& args) { | 100 static void GetLoadTimes(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 101 args.GetReturnValue().SetNull(); |
| 101 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); | 102 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); |
| 102 if (!frame) { | 103 if (!frame) { |
| 103 args.GetReturnValue().SetNull(); | |
| 104 return; | 104 return; |
| 105 } | 105 } |
| 106 WebDataSource* data_source = frame->dataSource(); | 106 WebDataSource* data_source = frame->dataSource(); |
| 107 if (!data_source) { | 107 if (!data_source) { |
| 108 args.GetReturnValue().SetNull(); | |
| 109 return; | 108 return; |
| 110 } | 109 } |
| 111 DocumentState* document_state = DocumentState::FromDataSource(data_source); | 110 DocumentState* document_state = DocumentState::FromDataSource(data_source); |
| 112 if (!document_state) { | 111 if (!document_state) { |
| 113 args.GetReturnValue().SetNull(); | |
| 114 return; | 112 return; |
| 115 } | 113 } |
| 116 double request_time = document_state->request_time().ToDoubleT(); | 114 double request_time = document_state->request_time().ToDoubleT(); |
| 117 double start_load_time = document_state->start_load_time().ToDoubleT(); | 115 double start_load_time = document_state->start_load_time().ToDoubleT(); |
| 118 double commit_load_time = document_state->commit_load_time().ToDoubleT(); | 116 double commit_load_time = document_state->commit_load_time().ToDoubleT(); |
| 119 double finish_document_load_time = | 117 double finish_document_load_time = |
| 120 document_state->finish_document_load_time().ToDoubleT(); | 118 document_state->finish_document_load_time().ToDoubleT(); |
| 121 double finish_load_time = document_state->finish_load_time().ToDoubleT(); | 119 double finish_load_time = document_state->finish_load_time().ToDoubleT(); |
| 122 double first_paint_time = document_state->first_paint_time().ToDoubleT(); | 120 double first_paint_time = document_state->first_paint_time().ToDoubleT(); |
| 123 double first_paint_after_load_time = | 121 double first_paint_after_load_time = |
| 124 document_state->first_paint_after_load_time().ToDoubleT(); | 122 document_state->first_paint_after_load_time().ToDoubleT(); |
| 125 std::string navigation_type = | 123 std::string navigation_type = |
| 126 GetNavigationType(data_source->navigationType()); | 124 GetNavigationType(data_source->navigationType()); |
| 127 bool was_fetched_via_spdy = document_state->was_fetched_via_spdy(); | 125 bool was_fetched_via_spdy = document_state->was_fetched_via_spdy(); |
| 128 bool was_npn_negotiated = document_state->was_npn_negotiated(); | 126 bool was_npn_negotiated = document_state->was_npn_negotiated(); |
| 129 std::string npn_negotiated_protocol = | 127 std::string npn_negotiated_protocol = |
| 130 document_state->npn_negotiated_protocol(); | 128 document_state->npn_negotiated_protocol(); |
| 131 bool was_alternate_protocol_available = | 129 bool was_alternate_protocol_available = |
| 132 document_state->was_alternate_protocol_available(); | 130 document_state->was_alternate_protocol_available(); |
| 133 std::string connection_info = net::HttpResponseInfo::ConnectionInfoToString( | 131 std::string connection_info = net::HttpResponseInfo::ConnectionInfoToString( |
| 134 document_state->connection_info()); | 132 document_state->connection_info()); |
| 135 // Important: |frame|, |data_source| and |document_state| should not be | 133 // Important: |frame|, |data_source| and |document_state| should not be |
| 136 // referred to below this line, as JS setters below can invalidate these | 134 // referred to below this line, as JS setters below can invalidate these |
| 137 // pointers. | 135 // pointers. |
| 138 v8::Isolate* isolate = args.GetIsolate(); | 136 v8::Isolate* isolate = args.GetIsolate(); |
| 137 v8::Local<v8::Context> ctx = isolate->GetCurrentContext(); |
| 139 v8::Local<v8::Object> load_times = v8::Object::New(isolate); | 138 v8::Local<v8::Object> load_times = v8::Object::New(isolate); |
| 140 load_times->Set(v8::String::NewFromUtf8(isolate, "requestTime"), | 139 if (!load_times |
| 141 v8::Number::New(isolate, request_time)); | 140 ->Set(ctx, v8::String::NewFromUtf8(isolate, "requestTime", |
| 142 load_times->Set(v8::String::NewFromUtf8(isolate, "startLoadTime"), | 141 v8::NewStringType::kNormal) |
| 143 v8::Number::New(isolate, start_load_time)); | 142 .ToLocalChecked(), |
| 144 load_times->Set(v8::String::NewFromUtf8(isolate, "commitLoadTime"), | 143 v8::Number::New(isolate, request_time)) |
| 145 v8::Number::New(isolate, commit_load_time)); | 144 .FromMaybe(false)) { |
| 146 load_times->Set(v8::String::NewFromUtf8(isolate, "finishDocumentLoadTime"), | 145 return; |
| 147 v8::Number::New(isolate, finish_document_load_time)); | 146 } |
| 148 load_times->Set(v8::String::NewFromUtf8(isolate, "finishLoadTime"), | 147 |
| 149 v8::Number::New(isolate, finish_load_time)); | 148 if (!load_times |
| 150 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintTime"), | 149 ->Set(ctx, v8::String::NewFromUtf8(isolate, "startLoadTime", |
| 151 v8::Number::New(isolate, first_paint_time)); | 150 v8::NewStringType::kNormal) |
| 152 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintAfterLoadTime"), | 151 .ToLocalChecked(), |
| 153 v8::Number::New(isolate, first_paint_after_load_time)); | 152 v8::Number::New(isolate, start_load_time)) |
| 154 load_times->Set(v8::String::NewFromUtf8(isolate, "navigationType"), | 153 .FromMaybe(false)) { |
| 155 v8::String::NewFromUtf8(isolate, navigation_type.c_str())); | 154 return; |
| 156 load_times->Set(v8::String::NewFromUtf8(isolate, "wasFetchedViaSpdy"), | 155 } |
| 157 v8::Boolean::New(isolate, was_fetched_via_spdy)); | 156 if (!load_times |
| 158 load_times->Set(v8::String::NewFromUtf8(isolate, "wasNpnNegotiated"), | 157 ->Set(ctx, v8::String::NewFromUtf8(isolate, "commitLoadTime", |
| 159 v8::Boolean::New(isolate, was_npn_negotiated)); | 158 v8::NewStringType::kNormal) |
| 160 load_times->Set( | 159 .ToLocalChecked(), |
| 161 v8::String::NewFromUtf8(isolate, "npnNegotiatedProtocol"), | 160 v8::Number::New(isolate, commit_load_time)) |
| 162 v8::String::NewFromUtf8(isolate, npn_negotiated_protocol.c_str())); | 161 .FromMaybe(false)) { |
| 163 load_times->Set( | 162 return; |
| 164 v8::String::NewFromUtf8(isolate, "wasAlternateProtocolAvailable"), | 163 } |
| 165 v8::Boolean::New(isolate, was_alternate_protocol_available)); | 164 if (!load_times |
| 166 load_times->Set(v8::String::NewFromUtf8(isolate, "connectionInfo"), | 165 ->Set(ctx, |
| 167 v8::String::NewFromUtf8(isolate, connection_info.c_str())); | 166 v8::String::NewFromUtf8(isolate, "finishDocumentLoadTime", |
| 167 v8::NewStringType::kNormal) |
| 168 .ToLocalChecked(), |
| 169 v8::Number::New(isolate, finish_document_load_time)) |
| 170 .FromMaybe(false)) { |
| 171 return; |
| 172 } |
| 173 if (!load_times |
| 174 ->Set(ctx, v8::String::NewFromUtf8(isolate, "finishLoadTime", |
| 175 v8::NewStringType::kNormal) |
| 176 .ToLocalChecked(), |
| 177 v8::Number::New(isolate, finish_load_time)) |
| 178 .FromMaybe(false)) { |
| 179 return; |
| 180 } |
| 181 if (!load_times |
| 182 ->Set(ctx, v8::String::NewFromUtf8(isolate, "firstPaintTime", |
| 183 v8::NewStringType::kNormal) |
| 184 .ToLocalChecked(), |
| 185 v8::Number::New(isolate, first_paint_time)) |
| 186 .FromMaybe(false)) { |
| 187 return; |
| 188 } |
| 189 if (!load_times |
| 190 ->Set(ctx, |
| 191 v8::String::NewFromUtf8(isolate, "firstPaintAfterLoadTime", |
| 192 v8::NewStringType::kNormal) |
| 193 .ToLocalChecked(), |
| 194 v8::Number::New(isolate, first_paint_after_load_time)) |
| 195 .FromMaybe(false)) { |
| 196 return; |
| 197 } |
| 198 if (!load_times |
| 199 ->Set(ctx, v8::String::NewFromUtf8(isolate, "navigationType", |
| 200 v8::NewStringType::kNormal) |
| 201 .ToLocalChecked(), |
| 202 v8::String::NewFromUtf8(isolate, navigation_type.c_str(), |
| 203 v8::NewStringType::kNormal) |
| 204 .ToLocalChecked()) |
| 205 .FromMaybe(false)) { |
| 206 return; |
| 207 } |
| 208 if (!load_times |
| 209 ->Set(ctx, v8::String::NewFromUtf8(isolate, "wasFetchedViaSpdy", |
| 210 v8::NewStringType::kNormal) |
| 211 .ToLocalChecked(), |
| 212 v8::Boolean::New(isolate, was_fetched_via_spdy)) |
| 213 .FromMaybe(false)) { |
| 214 return; |
| 215 } |
| 216 if (!load_times |
| 217 ->Set(ctx, v8::String::NewFromUtf8(isolate, "wasNpnNegotiated", |
| 218 v8::NewStringType::kNormal) |
| 219 .ToLocalChecked(), |
| 220 v8::Boolean::New(isolate, was_npn_negotiated)) |
| 221 .FromMaybe(false)) { |
| 222 return; |
| 223 } |
| 224 if (!load_times |
| 225 ->Set(ctx, |
| 226 v8::String::NewFromUtf8(isolate, "npnNegotiatedProtocol", |
| 227 v8::NewStringType::kNormal) |
| 228 .ToLocalChecked(), |
| 229 v8::String::NewFromUtf8(isolate, |
| 230 npn_negotiated_protocol.c_str(), |
| 231 v8::NewStringType::kNormal) |
| 232 .ToLocalChecked()) |
| 233 .FromMaybe(false)) { |
| 234 return; |
| 235 } |
| 236 if (!load_times |
| 237 ->Set(ctx, v8::String::NewFromUtf8(isolate, |
| 238 "wasAlternateProtocolAvailable", |
| 239 v8::NewStringType::kNormal) |
| 240 .ToLocalChecked(), |
| 241 v8::Boolean::New(isolate, was_alternate_protocol_available)) |
| 242 .FromMaybe(false)) { |
| 243 return; |
| 244 } |
| 245 if (!load_times |
| 246 ->Set(ctx, v8::String::NewFromUtf8(isolate, "connectionInfo", |
| 247 v8::NewStringType::kNormal) |
| 248 .ToLocalChecked(), |
| 249 v8::String::NewFromUtf8(isolate, connection_info.c_str(), |
| 250 v8::NewStringType::kNormal) |
| 251 .ToLocalChecked()) |
| 252 .FromMaybe(false)) { |
| 253 return; |
| 254 } |
| 168 args.GetReturnValue().Set(load_times); | 255 args.GetReturnValue().Set(load_times); |
| 169 } | 256 } |
| 170 | 257 |
| 171 static void GetCSI(const v8::FunctionCallbackInfo<v8::Value>& args) { | 258 static void GetCSI(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 259 args.GetReturnValue().SetNull(); |
| 172 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); | 260 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); |
| 173 if (frame) { | 261 if (!frame) { |
| 174 WebDataSource* data_source = frame->dataSource(); | 262 return; |
| 175 if (data_source) { | |
| 176 DocumentState* document_state = | |
| 177 DocumentState::FromDataSource(data_source); | |
| 178 v8::Isolate* isolate = args.GetIsolate(); | |
| 179 v8::Local<v8::Object> csi = v8::Object::New(isolate); | |
| 180 base::Time now = base::Time::Now(); | |
| 181 base::Time start = document_state->request_time().is_null() ? | |
| 182 document_state->start_load_time() : | |
| 183 document_state->request_time(); | |
| 184 base::Time onload = document_state->finish_document_load_time(); | |
| 185 base::TimeDelta page = now - start; | |
| 186 csi->Set(v8::String::NewFromUtf8(isolate, "startE"), | |
| 187 v8::Number::New(isolate, floor(start.ToDoubleT() * 1000))); | |
| 188 csi->Set(v8::String::NewFromUtf8(isolate, "onloadT"), | |
| 189 v8::Number::New(isolate, floor(onload.ToDoubleT() * 1000))); | |
| 190 csi->Set(v8::String::NewFromUtf8(isolate, "pageT"), | |
| 191 v8::Number::New(isolate, page.InMillisecondsF())); | |
| 192 csi->Set( | |
| 193 v8::String::NewFromUtf8(isolate, "tran"), | |
| 194 v8::Number::New( | |
| 195 isolate, GetCSITransitionType(data_source->navigationType()))); | |
| 196 | |
| 197 args.GetReturnValue().Set(csi); | |
| 198 return; | |
| 199 } | |
| 200 } | 263 } |
| 201 args.GetReturnValue().SetNull(); | 264 WebDataSource* data_source = frame->dataSource(); |
| 202 return; | 265 if (!data_source) { |
| 266 return; |
| 267 } |
| 268 DocumentState* document_state = DocumentState::FromDataSource(data_source); |
| 269 if (!document_state) { |
| 270 return; |
| 271 } |
| 272 base::Time now = base::Time::Now(); |
| 273 base::Time start = document_state->request_time().is_null() |
| 274 ? document_state->start_load_time() |
| 275 : document_state->request_time(); |
| 276 base::Time onload = document_state->finish_document_load_time(); |
| 277 base::TimeDelta page = now - start; |
| 278 int navigation_type = GetCSITransitionType(data_source->navigationType()); |
| 279 // Important: |frame|, |data_source| and |document_state| should not be |
| 280 // referred to below this line, as JS setters below can invalidate these |
| 281 // pointers. |
| 282 v8::Isolate* isolate = args.GetIsolate(); |
| 283 v8::Local<v8::Context> ctx = isolate->GetCurrentContext(); |
| 284 v8::Local<v8::Object> csi = v8::Object::New(isolate); |
| 285 if (!csi->Set(ctx, v8::String::NewFromUtf8(isolate, "startE", |
| 286 v8::NewStringType::kNormal) |
| 287 .ToLocalChecked(), |
| 288 v8::Number::New(isolate, floor(start.ToDoubleT() * 1000))) |
| 289 .FromMaybe(false)) { |
| 290 return; |
| 291 } |
| 292 if (!csi->Set(ctx, v8::String::NewFromUtf8(isolate, "onloadT", |
| 293 v8::NewStringType::kNormal) |
| 294 .ToLocalChecked(), |
| 295 v8::Number::New(isolate, floor(onload.ToDoubleT() * 1000))) |
| 296 .FromMaybe(false)) { |
| 297 return; |
| 298 } |
| 299 if (!csi->Set(ctx, v8::String::NewFromUtf8(isolate, "pageT", |
| 300 v8::NewStringType::kNormal) |
| 301 .ToLocalChecked(), |
| 302 v8::Number::New(isolate, page.InMillisecondsF())) |
| 303 .FromMaybe(false)) { |
| 304 return; |
| 305 } |
| 306 if (!csi->Set(ctx, v8::String::NewFromUtf8(isolate, "tran", |
| 307 v8::NewStringType::kNormal) |
| 308 .ToLocalChecked(), |
| 309 v8::Number::New(isolate, navigation_type)) |
| 310 .FromMaybe(false)) { |
| 311 return; |
| 312 } |
| 313 args.GetReturnValue().Set(csi); |
| 203 } | 314 } |
| 204 }; | 315 }; |
| 205 | 316 |
| 206 v8::Extension* LoadTimesExtension::Get() { | 317 v8::Extension* LoadTimesExtension::Get() { |
| 207 return new LoadTimesExtensionWrapper(); | 318 return new LoadTimesExtensionWrapper(); |
| 208 } | 319 } |
| 209 | 320 |
| 210 } // namespace extensions_v8 | 321 } // namespace extensions_v8 |
| OLD | NEW |