diff options
author | tyoverby@chromium.org <tyoverby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-10 08:47:27 +0000 |
---|---|---|
committer | tyoverby@chromium.org <tyoverby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-10 08:47:27 +0000 |
commit | 30565a8101f3cc03c8b334873f59c596d2600e3e (patch) | |
tree | 21316f1af46e8ed52bb7bc44a7cb54bf3bbc4cd2 /content/browser/resources | |
parent | 85698b90df0d1aecba2d046456b84385ed9d8532 (diff) | |
download | chromium_src-30565a8101f3cc03c8b334873f59c596d2600e3e.zip chromium_src-30565a8101f3cc03c8b334873f59c596d2600e3e.tar.gz chromium_src-30565a8101f3cc03c8b334873f59c596d2600e3e.tar.bz2 |
Adds cache and buffer graphs to the properties pane.
BUG=260005
Review URL: https://chromiumcodereview.appspot.com/23536020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222221 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/resources')
6 files changed, 212 insertions, 27 deletions
diff --git a/content/browser/resources/media/cache_entry.js b/content/browser/resources/media/cache_entry.js index 275a8c7..e4b3f0d 100644 --- a/content/browser/resources/media/cache_entry.js +++ b/content/browser/resources/media/cache_entry.js @@ -176,6 +176,12 @@ cr.define('media', function() { * this file. */ generateDetails: function() { + function makeElement(tag, content) { + var toReturn = document.createElement(tag); + toReturn.textContent = content; + return toReturn; + } + this.details_.id = this.key; this.summaryText_.textContent = this.key || 'Unknown File'; @@ -188,8 +194,8 @@ cr.define('media', function() { this.detailTable_.appendChild(body); var headerRow = document.createElement('tr'); - headerRow.appendChild(media.makeElement('th', 'Read From Cache')); - headerRow.appendChild(media.makeElement('th', 'Written To Cache')); + headerRow.appendChild(makeElement('th', 'Read From Cache')); + headerRow.appendChild(makeElement('th', 'Written To Cache')); header.appendChild(headerRow); var footerRow = document.createElement('tr'); @@ -209,8 +215,8 @@ cr.define('media', function() { var length = Math.max(read.length, written.length); for (var i = 0; i < length; i++) { var row = document.createElement('tr'); - row.appendChild(media.makeElement('td', read[i] || '')); - row.appendChild(media.makeElement('td', written[i] || '')); + row.appendChild(makeElement('td', read[i] || '')); + row.appendChild(makeElement('td', written[i] || '')); body.appendChild(row); } diff --git a/content/browser/resources/media/new/client_renderer.js b/content/browser/resources/media/new/client_renderer.js index 02f47e1..52dd92d 100644 --- a/content/browser/resources/media/new/client_renderer.js +++ b/content/browser/resources/media/new/client_renderer.js @@ -8,11 +8,16 @@ var ClientRenderer = (function() { this.audioStreamListElement = document.getElementById('audio-stream-list'); this.propertiesTable = document.getElementById('property-table'); this.logTable = document.getElementById('log'); + this.graphElement = document.getElementById('graphs'); this.selectedPlayer = null; this.selectedStream = null; this.selectedPlayerLogIndex = 0; + + this.bufferCanvas = document.createElement('canvas'); + this.bufferCanvas.width = media.BAR_WIDTH; + this.bufferCanvas.height = media.BAR_HEIGHT; }; function removeChildren(element) { @@ -76,6 +81,7 @@ var ClientRenderer = (function() { if (player === this.selectedPlayer) { this.drawProperties_(player.properties); this.drawLog_(); + this.drawGraphs_(); } if (key === 'name' || key === 'url') { this.redrawPlayerList_(players); @@ -98,6 +104,7 @@ var ClientRenderer = (function() { this.selectedPlayer = null; this.drawProperties_(audioStream); removeChildren(this.logTable.querySelector('tbody')); + removeChildren(this.graphElement); }, redrawPlayerList_: function(players) { @@ -123,7 +130,9 @@ var ClientRenderer = (function() { this.drawProperties_(player.properties); removeChildren(this.logTable.querySelector('tbody')); + removeChildren(this.graphElement); this.drawLog_(); + this.drawGraphs_(); }, drawProperties_: function(propertyMap) { @@ -131,6 +140,7 @@ var ClientRenderer = (function() { for (key in propertyMap) { var value = propertyMap[key]; + var row = this.propertiesTable.insertRow(-1); var keyCell = row.insertCell(-1); var valueCell = row.insertCell(-1); @@ -154,6 +164,76 @@ var ClientRenderer = (function() { this.selectedPlayerLogIndex); toDraw.forEach(this.appendEventToLog_.bind(this)); this.selectedPlayerLogIndex = this.selectedPlayer.allEvents.length; + }, + + drawGraphs_: function() { + function addToGraphs (name, graph, graphElement) { + var li = document.createElement('li'); + li.appendChild(graph); + li.appendChild(document.createTextNode(name)); + graphElement.appendChild(li); + } + + var url = this.selectedPlayer.properties.url; + if (!url) { + return; + } + + var cache = media.cacheForUrl(url); + + var player = this.selectedPlayer; + var props = player.properties; + + var cacheExists = false; + var bufferExists = false; + + if (props['buffer_start'] !== undefined && + props['buffer_current'] !== undefined && + props['buffer_end'] !== undefined && + props['total_bytes'] !== undefined) { + this.drawBufferGraph_(props['buffer_start'], + props['buffer_current'], + props['buffer_end'], + props['total_bytes']); + bufferExists = true; + } + + if (cache) { + if(player.properties['total_bytes']) { + cache.size = Number(player.properties['total_bytes']); + } + cache.generateDetails(); + cacheExists = true; + + } + + if (!this.graphElement.hasChildNodes()) { + if (bufferExists) { + addToGraphs('buffer', this.bufferCanvas, this.graphElement); + } + if (cacheExists) { + addToGraphs('cache read', cache.readCanvas, this.graphElement); + addToGraphs('cache write', cache.writeCanvas, this.graphElement); + } + } + }, + + drawBufferGraph_: function(start, current, end, size) { + var ctx = this.bufferCanvas.getContext('2d'); + var width = this.bufferCanvas.width; + var height = this.bufferCanvas.height; + ctx.fillStyle = '#aaa'; + ctx.fillRect(0, 0, width, height); + + var scale_factor = width / size; + var left = start * scale_factor; + var middle = current * scale_factor; + var right = end * scale_factor; + + ctx.fillStyle = '#a0a'; + ctx.fillRect(left, 0, middle - left, height); + ctx.fillStyle = '#aa0'; + ctx.fillRect(middle, 0, right - middle, height); } }; diff --git a/content/browser/resources/media/new/main.js b/content/browser/resources/media/new/main.js index 85cdd3a..14b9918 100644 --- a/content/browser/resources/media/new/main.js +++ b/content/browser/resources/media/new/main.js @@ -8,13 +8,35 @@ var media = (function() { 'use strict'; - var manager_ = null; + var manager = null; + + // A number->string mapping that is populated through the backend that + // describes the phase that the network entity is in. + var eventPhases = {}; + + // A number->string mapping that is populated through the backend that + // describes the type of event sent from the network. + var eventTypes = {}; + + // A mapping of number->CacheEntry where the number is a unique id for that + // network request. + var cacheEntries = {}; + + // A mapping of url->CacheEntity where the url is the url of the resource. + var cacheEntriesByKey = {}; + + var requrestURLs = {}; + + var media = { + BAR_WIDTH: 200, + BAR_HEIGHT: 25 + }; /** * Users of |media| must call initialize prior to calling other methods. */ - media.initialize = function(manager) { - manager_ = manager; + media.initialize = function(theManager) { + manager = theManager; }; media.onReceiveEverything = function(everything) { @@ -23,14 +45,80 @@ var media = (function() { } }; - media.onNetUpdate = function(update) { - // TODO(tyoverby): Implement + media.onReceiveConstants = function(constants) { + for (var key in constants.eventTypes) { + var value = constants.eventTypes[key]; + eventTypes[value] = key; + } + + for (var key in constants.eventPhases) { + var value = constants.eventPhases[key]; + eventPhases[value] = key; + } + }; + + media.cacheForUrl = function(url) { + return cacheEntriesByKey[url]; + }; + + media.onNetUpdate = function(updates) { + updates.forEach(function(update) { + var id = update.source.id; + if (!cacheEntries[id]) + cacheEntries[id] = new media.CacheEntry; + + switch (eventPhases[update.phase] + '.' + eventTypes[update.type]) { + case 'PHASE_BEGIN.DISK_CACHE_ENTRY_IMPL': + var key = update.params.key; + + // Merge this source with anything we already know about this key. + if (cacheEntriesByKey[key]) { + cacheEntriesByKey[key].merge(cacheEntries[id]); + cacheEntries[id] = cacheEntriesByKey[key]; + } else { + cacheEntriesByKey[key] = cacheEntries[id]; + } + cacheEntriesByKey[key].key = key; + break; + + case 'PHASE_BEGIN.SPARSE_READ': + cacheEntries[id].readBytes(update.params.offset, + update.params.buff_len); + cacheEntries[id].sparse = true; + break; + + case 'PHASE_BEGIN.SPARSE_WRITE': + cacheEntries[id].writeBytes(update.params.offset, + update.params.buff_len); + cacheEntries[id].sparse = true; + break; + + case 'PHASE_BEGIN.URL_REQUEST_START_JOB': + requrestURLs[update.source.id] = update.params.url; + break; + + case 'PHASE_NONE.HTTP_TRANSACTION_READ_RESPONSE_HEADERS': + // Record the total size of the file if this was a range request. + var range = /content-range:\s*bytes\s*\d+-\d+\/(\d+)/i.exec( + update.params.headers); + var key = requrestURLs[update.source.id]; + delete requrestURLs[update.source.id]; + if (range && key) { + if (!cacheEntriesByKey[key]) { + cacheEntriesByKey[key] = new media.CacheEntry; + cacheEntriesByKey[key].key = key; + } + cacheEntriesByKey[key].size = range[1]; + } + break; + } + }); }; media.onRendererTerminated = function(renderId) { - util.object.forEach(manager_.players_, function(playerInfo, id) { + util.object.forEach(manager.players_, function(playerInfo, id) { if (playerInfo.properties['render_id'] == renderId) { - manager_.removePlayer(id); + manager.removePlayer(id); } }); }; @@ -40,18 +128,18 @@ var media = (function() { media.addAudioStream = function(event) { switch (event.status) { case 'created': - manager_.addAudioStream(event.id); - manager_.updateAudioStream(event.id, { 'playing': event.playing }); + manager.addAudioStream(event.id); + manager.updateAudioStream(event.id, { 'playing': event.playing }); break; case 'closed': - manager_.removeAudioStream(event.id); + manager.removeAudioStream(event.id); break; } }; media.updateAudioStream = function(stream) { - manager_.addAudioStream(stream.id); - manager_.updateAudioStream(stream.id, stream); + manager.addAudioStream(stream.id); + manager.updateAudioStream(stream.id, stream); }; media.onItemDeleted = function() { @@ -61,7 +149,7 @@ var media = (function() { }; media.onPlayerOpen = function(id, timestamp) { - manager_.addPlayer(id, timestamp); + manager.addPlayer(id, timestamp); }; media.onMediaEvent = function(event) { @@ -70,9 +158,9 @@ var media = (function() { // Although this gets called on every event, there is nothing we can do // because there is no onOpen event. media.onPlayerOpen(source); - manager_.updatePlayerInfoNoRecord( + manager.updatePlayerInfoNoRecord( source, event.ticksMillis, 'render_id', event.renderer); - manager_.updatePlayerInfoNoRecord( + manager.updatePlayerInfoNoRecord( source, event.ticksMillis, 'player_id', event.player); var propertyCount = 0; @@ -85,19 +173,23 @@ var media = (function() { key === 'buffer_end' || key === 'buffer_current' || key === 'is_downloading_data') { - manager_.updatePlayerInfoNoRecord( + manager.updatePlayerInfoNoRecord( source, event.ticksMillis, key, value); } else { - manager_.updatePlayerInfo(source, event.ticksMillis, key, value); + manager.updatePlayerInfo(source, event.ticksMillis, key, value); } propertyCount += 1; }); if (propertyCount === 0) { - manager_.updatePlayerInfo( + manager.updatePlayerInfo( source, event.ticksMillis, 'EVENT', event.type); } }; + // |chrome| is not defined during tests. + if (window.chrome && window.chrome.send) { + chrome.send('getEverything'); + } return media; }()); diff --git a/content/browser/resources/media/new/media_internals.css b/content/browser/resources/media/new/media_internals.css index 88a792b..b747fb9 100644 --- a/content/browser/resources/media/new/media_internals.css +++ b/content/browser/resources/media/new/media_internals.css @@ -18,6 +18,8 @@ table { } td { border: 1px solid black; + word-wrap: break-word; + max-width: 200px; } thead { color: rgb(50,50,50); @@ -43,7 +45,6 @@ h3 { padding: 0; padding-left: 25px; margin: 0; - max-height: 100%; } #list-wrapper { @@ -52,7 +53,6 @@ h3 { justify-content: space-between; align-items: flex-start; align-content: stretch; - height: 100%; } #player-list-wrapper, @@ -89,3 +89,7 @@ h3 { #log-wrapper > thead { position: fixed; } + +#graphs li { + list-style-type: none; +} diff --git a/content/browser/resources/media/new/media_internals.html b/content/browser/resources/media/new/media_internals.html index 8a41e7f..fc9e73b 100644 --- a/content/browser/resources/media/new/media_internals.html +++ b/content/browser/resources/media/new/media_internals.html @@ -9,6 +9,7 @@ found in the LICENSE file. <meta charset="utf-8"> <title i18n-content="Media Internals"></title> <link rel="stylesheet" href="media_internals.css"> + <script src="chrome://resources/js/cr.js"></script> </head> <body> @@ -32,6 +33,7 @@ found in the LICENSE file. </tr> </thead> </table> + <ul id="graphs"></ul> </div> <div id="log-wrapper"> <h2> @@ -45,8 +47,7 @@ found in the LICENSE file. <td>Value</td> </tr> </thead> - <tbody> - </tbody> + <tbody></tbody> </table> </div> </div> diff --git a/content/browser/resources/media/new/media_internals.js b/content/browser/resources/media/new/media_internals.js index ced99d5..d1b662e 100644 --- a/content/browser/resources/media/new/media_internals.js +++ b/content/browser/resources/media/new/media_internals.js @@ -4,10 +4,12 @@ var media = {}; +<include src="main.js"/> <include src="util.js"/> +<include src="../cache_entry.js"/> +<include src="../disjoint_range_set.js"/> <include src="player_info.js"/> <include src="manager.js"/> <include src="client_renderer.js"/> -<include src="main.js"/> media.initialize(new Manager(new ClientRenderer())); |