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 |