| 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 /** | 5 /** |
| 6 * @constructor | 6 * @constructor |
| 7 * @implements {WebInspector.OutputStream} | 7 * @implements {WebInspector.OutputStream} |
| 8 * @implements {WebInspector.OutputStreamDelegate} | 8 * @implements {WebInspector.OutputStreamDelegate} |
| 9 * @param {!WebInspector.TimelineModel} model | 9 * @param {!WebInspector.TracingModel} model |
| 10 * @param {!WebInspector.Progress} progress | 10 * @param {!WebInspector.TimelineLifecycleDelegate} delegate |
| 11 */ | 11 */ |
| 12 WebInspector.TimelineLoader = function(model, progress) | 12 WebInspector.TimelineLoader = function(model, delegate) |
| 13 { | 13 { |
| 14 this._model = model; | 14 this._model = model; |
| 15 this._delegate = delegate; |
| 15 | 16 |
| 16 /** @type {?function()} */ | 17 /** @type {?function()} */ |
| 17 this._canceledCallback = null; | 18 this._canceledCallback = null; |
| 18 this._progress = progress; | |
| 19 this._progress.setTitle(WebInspector.UIString("Loading")); | |
| 20 this._progress.setTotalWork(WebInspector.TimelineLoader._totalProgress); //
Unknown, will loop the values. | |
| 21 | 19 |
| 22 this._state = WebInspector.TimelineLoader.State.Initial; | 20 this._state = WebInspector.TimelineLoader.State.Initial; |
| 23 this._buffer = ""; | 21 this._buffer = ""; |
| 24 this._firstChunk = true; | 22 this._firstChunk = true; |
| 25 this._wasCanceledOnce = false; | |
| 26 | 23 |
| 27 this._loadedBytes = 0; | 24 this._loadedBytes = 0; |
| 28 /** @type {number} */ | 25 /** @type {number} */ |
| 29 this._totalSize; | 26 this._totalSize; |
| 30 this._jsonTokenizer = new WebInspector.TextUtils.BalancedJSONTokenizer(this.
_writeBalancedJSON.bind(this), true); | 27 this._jsonTokenizer = new WebInspector.TextUtils.BalancedJSONTokenizer(this.
_writeBalancedJSON.bind(this), true); |
| 31 } | 28 } |
| 32 | 29 |
| 33 /** | 30 /** |
| 34 * @param {!WebInspector.TimelineModel} model | 31 * @param {!WebInspector.TracingModel} model |
| 35 * @param {!File} file | 32 * @param {!File} file |
| 36 * @param {!WebInspector.Progress} progress | 33 * @param {!WebInspector.TimelineLifecycleDelegate} delegate |
| 34 * @return {!WebInspector.TimelineLoader} |
| 37 */ | 35 */ |
| 38 WebInspector.TimelineLoader.loadFromFile = function(model, file, progress) | 36 WebInspector.TimelineLoader.loadFromFile = function(model, file, delegate) |
| 39 { | 37 { |
| 40 var loader = new WebInspector.TimelineLoader(model, progress); | 38 var loader = new WebInspector.TimelineLoader(model, delegate); |
| 41 var fileReader = WebInspector.TimelineLoader._createFileReader(file, loader)
; | 39 var fileReader = WebInspector.TimelineLoader._createFileReader(file, loader)
; |
| 42 loader._canceledCallback = fileReader.cancel.bind(fileReader); | 40 loader._canceledCallback = fileReader.cancel.bind(fileReader); |
| 43 loader._totalSize = file.size; | 41 loader._totalSize = file.size; |
| 44 progress.setTotalWork(loader._totalSize); | |
| 45 fileReader.start(loader); | 42 fileReader.start(loader); |
| 43 return loader; |
| 46 } | 44 } |
| 47 | 45 |
| 48 /** | 46 /** |
| 49 * @param {!WebInspector.TimelineModel} model | 47 * @param {!WebInspector.TracingModel} model |
| 50 * @param {string} url | 48 * @param {string} url |
| 51 * @param {!WebInspector.Progress} progress | 49 * @param {!WebInspector.TimelineLifecycleDelegate} delegate |
| 50 * @return {!WebInspector.TimelineLoader} |
| 52 */ | 51 */ |
| 53 WebInspector.TimelineLoader.loadFromURL = function(model, url, progress) | 52 WebInspector.TimelineLoader.loadFromURL = function(model, url, delegate) |
| 54 { | 53 { |
| 55 var stream = new WebInspector.TimelineLoader(model, progress); | 54 var stream = new WebInspector.TimelineLoader(model, delegate); |
| 56 WebInspector.ResourceLoader.loadAsStream(url, null, stream); | 55 WebInspector.ResourceLoader.loadAsStream(url, null, stream); |
| 56 return stream; |
| 57 } | 57 } |
| 58 | 58 |
| 59 WebInspector.TimelineLoader.TransferChunkLengthBytes = 5000000; |
| 60 |
| 59 /** | 61 /** |
| 60 * @param {!File} file | 62 * @param {!File} file |
| 61 * @param {!WebInspector.OutputStreamDelegate} delegate | 63 * @param {!WebInspector.OutputStreamDelegate} delegate |
| 62 * @return {!WebInspector.ChunkedReader} | 64 * @return {!WebInspector.ChunkedReader} |
| 63 */ | 65 */ |
| 64 WebInspector.TimelineLoader._createFileReader = function(file, delegate) | 66 WebInspector.TimelineLoader._createFileReader = function(file, delegate) |
| 65 { | 67 { |
| 66 return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModel.T
ransferChunkLengthBytes, delegate); | 68 return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineLoader.
TransferChunkLengthBytes, delegate); |
| 67 } | 69 } |
| 68 | 70 |
| 69 | |
| 70 WebInspector.TimelineLoader._totalProgress = 100000; | |
| 71 | |
| 72 WebInspector.TimelineLoader.State = { | 71 WebInspector.TimelineLoader.State = { |
| 73 Initial: "Initial", | 72 Initial: "Initial", |
| 74 LookingForEvents: "LookingForEvents", | 73 LookingForEvents: "LookingForEvents", |
| 75 ReadingEvents: "ReadingEvents" | 74 ReadingEvents: "ReadingEvents" |
| 76 } | 75 } |
| 77 | 76 |
| 78 WebInspector.TimelineLoader.prototype = { | 77 WebInspector.TimelineLoader.prototype = { |
| 78 cancel: function() |
| 79 { |
| 80 this._model.reset(); |
| 81 this._delegate.loadingComplete(false); |
| 82 this._delegate = null; |
| 83 if (this._canceledCallback) |
| 84 this._canceledCallback(); |
| 85 }, |
| 86 |
| 79 /** | 87 /** |
| 80 * @override | 88 * @override |
| 81 * @param {string} chunk | 89 * @param {string} chunk |
| 82 */ | 90 */ |
| 83 write: function(chunk) | 91 write: function(chunk) |
| 84 { | 92 { |
| 93 if (!this._delegate) |
| 94 return; |
| 85 this._loadedBytes += chunk.length; | 95 this._loadedBytes += chunk.length; |
| 86 if (this._progress.isCanceled() && !this._wasCanceledOnce) { | 96 if (!this._firstChunk) |
| 87 this._wasCanceled = true; | 97 this._delegate.loadingProgress(this._totalSize ? this._loadedBytes /
this._totalSize : undefined); |
| 88 this._reportErrorAndCancelLoading(); | 98 |
| 89 return; | |
| 90 } | |
| 91 if (this._firstChunk) | |
| 92 this._progress.setTitle(WebInspector.UIString("Loading\u2026")); | |
| 93 if (this._totalSize) { | |
| 94 this._progress.setWorked(this._loadedBytes); | |
| 95 } else { | |
| 96 this._progress.setWorked(this._loadedBytes % WebInspector.TimelineLo
ader._totalProgress, | |
| 97 WebInspector.UIString("Loaded %s", Number.b
ytesToString(this._loadedBytes))); | |
| 98 } | |
| 99 if (this._state === WebInspector.TimelineLoader.State.Initial) { | 99 if (this._state === WebInspector.TimelineLoader.State.Initial) { |
| 100 if (chunk[0] === "{") | 100 if (chunk[0] === "{") |
| 101 this._state = WebInspector.TimelineLoader.State.LookingForEvents
; | 101 this._state = WebInspector.TimelineLoader.State.LookingForEvents
; |
| 102 else if (chunk[0] === "[") | 102 else if (chunk[0] === "[") |
| 103 this._state = WebInspector.TimelineLoader.State.ReadingEvents; | 103 this._state = WebInspector.TimelineLoader.State.ReadingEvents; |
| 104 else { | 104 else { |
| 105 this._reportErrorAndCancelLoading(WebInspector.UIString("Malform
ed timeline data: Unknown JSON format")); | 105 this._reportErrorAndCancelLoading(WebInspector.UIString("Malform
ed timeline data: Unknown JSON format")); |
| 106 return; | 106 return; |
| 107 } | 107 } |
| 108 } | 108 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 122 }, | 122 }, |
| 123 | 123 |
| 124 /** | 124 /** |
| 125 * @param {string} data | 125 * @param {string} data |
| 126 */ | 126 */ |
| 127 _writeBalancedJSON: function(data) | 127 _writeBalancedJSON: function(data) |
| 128 { | 128 { |
| 129 var json = data + "]"; | 129 var json = data + "]"; |
| 130 | 130 |
| 131 if (this._firstChunk) { | 131 if (this._firstChunk) { |
| 132 this._model.startCollectingTraceEvents(true); | 132 this._delegate.loadingStarted(); |
| 133 } else { | 133 } else { |
| 134 var commaIndex = json.indexOf(","); | 134 var commaIndex = json.indexOf(","); |
| 135 if (commaIndex !== -1) | 135 if (commaIndex !== -1) |
| 136 json = json.slice(commaIndex + 1); | 136 json = json.slice(commaIndex + 1); |
| 137 json = "[" + json; | 137 json = "[" + json; |
| 138 } | 138 } |
| 139 | 139 |
| 140 var items; | 140 var items; |
| 141 try { | 141 try { |
| 142 items = /** @type {!Array.<!WebInspector.TracingManager.EventPayload
>} */ (JSON.parse(json)); | 142 items = /** @type {!Array.<!WebInspector.TracingManager.EventPayload
>} */ (JSON.parse(json)); |
| 143 } catch (e) { | 143 } catch (e) { |
| 144 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t
imeline data: %s", e.toString())); | 144 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t
imeline data: %s", e.toString())); |
| 145 return; | 145 return; |
| 146 } | 146 } |
| 147 | 147 |
| 148 if (this._firstChunk) { | 148 if (this._firstChunk) { |
| 149 this._firstChunk = false; | 149 this._firstChunk = false; |
| 150 if (this._looksLikeAppVersion(items[0])) { | 150 if (this._looksLikeAppVersion(items[0])) { |
| 151 this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy
Timeline format is not supported.")); | 151 this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy
Timeline format is not supported.")); |
| 152 return; | 152 return; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 try { | 156 try { |
| 157 this._model.traceEventsCollected(items); | 157 this._model.addEvents(items); |
| 158 } catch(e) { | 158 } catch(e) { |
| 159 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t
imeline data: %s", e.toString())); | 159 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t
imeline data: %s", e.toString())); |
| 160 return; | 160 return; |
| 161 } | 161 } |
| 162 }, | 162 }, |
| 163 | 163 |
| 164 /** | 164 /** |
| 165 * @param {string=} message | 165 * @param {string=} message |
| 166 */ | 166 */ |
| 167 _reportErrorAndCancelLoading: function(message) | 167 _reportErrorAndCancelLoading: function(message) |
| 168 { | 168 { |
| 169 if (message) | 169 if (message) |
| 170 WebInspector.console.error(message); | 170 WebInspector.console.error(message); |
| 171 this._model.tracingComplete(); | 171 this.cancel(); |
| 172 this._model.reset(); | |
| 173 if (this._canceledCallback) | |
| 174 this._canceledCallback(); | |
| 175 this._progress.done(); | |
| 176 }, | 172 }, |
| 177 | 173 |
| 178 /** | 174 /** |
| 179 * @param {*} item | 175 * @param {*} item |
| 180 * @return {boolean} | 176 * @return {boolean} |
| 181 */ | 177 */ |
| 182 _looksLikeAppVersion: function(item) | 178 _looksLikeAppVersion: function(item) |
| 183 { | 179 { |
| 184 return typeof item === "string" && item.indexOf("Chrome") !== -1; | 180 return typeof item === "string" && item.indexOf("Chrome") !== -1; |
| 185 }, | 181 }, |
| 186 | 182 |
| 187 /** | 183 /** |
| 188 * @override | 184 * @override |
| 189 */ | 185 */ |
| 190 close: function() | 186 close: function() |
| 191 { | 187 { |
| 192 this._model._loadedFromFile = true; | 188 this._model._loadedFromFile = true; |
| 193 this._model.tracingComplete(); | 189 if (this._delegate) |
| 194 this._progress.done(); | 190 this._delegate.loadingComplete(true); |
| 195 }, | 191 }, |
| 196 | 192 |
| 197 /** | 193 /** |
| 198 * @override | 194 * @override |
| 199 */ | 195 */ |
| 200 onTransferStarted: function() {}, | 196 onTransferStarted: function() {}, |
| 201 | 197 |
| 202 /** | 198 /** |
| 203 * @override | 199 * @override |
| 204 * @param {!WebInspector.ChunkedReader} reader | 200 * @param {!WebInspector.ChunkedReader} reader |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 * @override | 257 * @override |
| 262 * @param {!WebInspector.ChunkedReader} reader | 258 * @param {!WebInspector.ChunkedReader} reader |
| 263 * @param {!Event} event | 259 * @param {!Event} event |
| 264 */ | 260 */ |
| 265 onError: function(reader, event) | 261 onError: function(reader, event) |
| 266 { | 262 { |
| 267 var error = event.target.error; | 263 var error = event.target.error; |
| 268 WebInspector.console.error(WebInspector.UIString("Failed to save timelin
e: %s (%s, %s)", error.message, error.name, error.code)); | 264 WebInspector.console.error(WebInspector.UIString("Failed to save timelin
e: %s (%s, %s)", error.message, error.name, error.code)); |
| 269 } | 265 } |
| 270 } | 266 } |
| OLD | NEW |