Commit 30565a81 authored by tyoverby@chromium.org's avatar tyoverby@chromium.org

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
parent 85698b90
...@@ -176,6 +176,12 @@ cr.define('media', function() { ...@@ -176,6 +176,12 @@ cr.define('media', function() {
* this file. * this file.
*/ */
generateDetails: function() { generateDetails: function() {
function makeElement(tag, content) {
var toReturn = document.createElement(tag);
toReturn.textContent = content;
return toReturn;
}
this.details_.id = this.key; this.details_.id = this.key;
this.summaryText_.textContent = this.key || 'Unknown File'; this.summaryText_.textContent = this.key || 'Unknown File';
...@@ -188,8 +194,8 @@ cr.define('media', function() { ...@@ -188,8 +194,8 @@ cr.define('media', function() {
this.detailTable_.appendChild(body); this.detailTable_.appendChild(body);
var headerRow = document.createElement('tr'); var headerRow = document.createElement('tr');
headerRow.appendChild(media.makeElement('th', 'Read From Cache')); headerRow.appendChild(makeElement('th', 'Read From Cache'));
headerRow.appendChild(media.makeElement('th', 'Written To Cache')); headerRow.appendChild(makeElement('th', 'Written To Cache'));
header.appendChild(headerRow); header.appendChild(headerRow);
var footerRow = document.createElement('tr'); var footerRow = document.createElement('tr');
...@@ -209,8 +215,8 @@ cr.define('media', function() { ...@@ -209,8 +215,8 @@ cr.define('media', function() {
var length = Math.max(read.length, written.length); var length = Math.max(read.length, written.length);
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
var row = document.createElement('tr'); var row = document.createElement('tr');
row.appendChild(media.makeElement('td', read[i] || '')); row.appendChild(makeElement('td', read[i] || ''));
row.appendChild(media.makeElement('td', written[i] || '')); row.appendChild(makeElement('td', written[i] || ''));
body.appendChild(row); body.appendChild(row);
} }
......
...@@ -8,11 +8,16 @@ var ClientRenderer = (function() { ...@@ -8,11 +8,16 @@ var ClientRenderer = (function() {
this.audioStreamListElement = document.getElementById('audio-stream-list'); this.audioStreamListElement = document.getElementById('audio-stream-list');
this.propertiesTable = document.getElementById('property-table'); this.propertiesTable = document.getElementById('property-table');
this.logTable = document.getElementById('log'); this.logTable = document.getElementById('log');
this.graphElement = document.getElementById('graphs');
this.selectedPlayer = null; this.selectedPlayer = null;
this.selectedStream = null; this.selectedStream = null;
this.selectedPlayerLogIndex = 0; this.selectedPlayerLogIndex = 0;
this.bufferCanvas = document.createElement('canvas');
this.bufferCanvas.width = media.BAR_WIDTH;
this.bufferCanvas.height = media.BAR_HEIGHT;
}; };
function removeChildren(element) { function removeChildren(element) {
...@@ -76,6 +81,7 @@ var ClientRenderer = (function() { ...@@ -76,6 +81,7 @@ var ClientRenderer = (function() {
if (player === this.selectedPlayer) { if (player === this.selectedPlayer) {
this.drawProperties_(player.properties); this.drawProperties_(player.properties);
this.drawLog_(); this.drawLog_();
this.drawGraphs_();
} }
if (key === 'name' || key === 'url') { if (key === 'name' || key === 'url') {
this.redrawPlayerList_(players); this.redrawPlayerList_(players);
...@@ -98,6 +104,7 @@ var ClientRenderer = (function() { ...@@ -98,6 +104,7 @@ var ClientRenderer = (function() {
this.selectedPlayer = null; this.selectedPlayer = null;
this.drawProperties_(audioStream); this.drawProperties_(audioStream);
removeChildren(this.logTable.querySelector('tbody')); removeChildren(this.logTable.querySelector('tbody'));
removeChildren(this.graphElement);
}, },
redrawPlayerList_: function(players) { redrawPlayerList_: function(players) {
...@@ -123,7 +130,9 @@ var ClientRenderer = (function() { ...@@ -123,7 +130,9 @@ var ClientRenderer = (function() {
this.drawProperties_(player.properties); this.drawProperties_(player.properties);
removeChildren(this.logTable.querySelector('tbody')); removeChildren(this.logTable.querySelector('tbody'));
removeChildren(this.graphElement);
this.drawLog_(); this.drawLog_();
this.drawGraphs_();
}, },
drawProperties_: function(propertyMap) { drawProperties_: function(propertyMap) {
...@@ -131,6 +140,7 @@ var ClientRenderer = (function() { ...@@ -131,6 +140,7 @@ var ClientRenderer = (function() {
for (key in propertyMap) { for (key in propertyMap) {
var value = propertyMap[key]; var value = propertyMap[key];
var row = this.propertiesTable.insertRow(-1); var row = this.propertiesTable.insertRow(-1);
var keyCell = row.insertCell(-1); var keyCell = row.insertCell(-1);
var valueCell = row.insertCell(-1); var valueCell = row.insertCell(-1);
...@@ -154,6 +164,76 @@ var ClientRenderer = (function() { ...@@ -154,6 +164,76 @@ var ClientRenderer = (function() {
this.selectedPlayerLogIndex); this.selectedPlayerLogIndex);
toDraw.forEach(this.appendEventToLog_.bind(this)); toDraw.forEach(this.appendEventToLog_.bind(this));
this.selectedPlayerLogIndex = this.selectedPlayer.allEvents.length; 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);
} }
}; };
......
...@@ -8,13 +8,35 @@ ...@@ -8,13 +8,35 @@
var media = (function() { var media = (function() {
'use strict'; '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. * Users of |media| must call initialize prior to calling other methods.
*/ */
media.initialize = function(manager) { media.initialize = function(theManager) {
manager_ = manager; manager = theManager;
}; };
media.onReceiveEverything = function(everything) { media.onReceiveEverything = function(everything) {
...@@ -23,14 +45,80 @@ var media = (function() { ...@@ -23,14 +45,80 @@ var media = (function() {
} }
}; };
media.onNetUpdate = function(update) { media.onReceiveConstants = function(constants) {
// TODO(tyoverby): Implement 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) { 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) { if (playerInfo.properties['render_id'] == renderId) {
manager_.removePlayer(id); manager.removePlayer(id);
} }
}); });
}; };
...@@ -40,18 +128,18 @@ var media = (function() { ...@@ -40,18 +128,18 @@ var media = (function() {
media.addAudioStream = function(event) { media.addAudioStream = function(event) {
switch (event.status) { switch (event.status) {
case 'created': case 'created':
manager_.addAudioStream(event.id); manager.addAudioStream(event.id);
manager_.updateAudioStream(event.id, { 'playing': event.playing }); manager.updateAudioStream(event.id, { 'playing': event.playing });
break; break;
case 'closed': case 'closed':
manager_.removeAudioStream(event.id); manager.removeAudioStream(event.id);
break; break;
} }
}; };
media.updateAudioStream = function(stream) { media.updateAudioStream = function(stream) {
manager_.addAudioStream(stream.id); manager.addAudioStream(stream.id);
manager_.updateAudioStream(stream.id, stream); manager.updateAudioStream(stream.id, stream);
}; };
media.onItemDeleted = function() { media.onItemDeleted = function() {
...@@ -61,7 +149,7 @@ var media = (function() { ...@@ -61,7 +149,7 @@ var media = (function() {
}; };
media.onPlayerOpen = function(id, timestamp) { media.onPlayerOpen = function(id, timestamp) {
manager_.addPlayer(id, timestamp); manager.addPlayer(id, timestamp);
}; };
media.onMediaEvent = function(event) { media.onMediaEvent = function(event) {
...@@ -70,9 +158,9 @@ var media = (function() { ...@@ -70,9 +158,9 @@ var media = (function() {
// Although this gets called on every event, there is nothing we can do // Although this gets called on every event, there is nothing we can do
// because there is no onOpen event. // because there is no onOpen event.
media.onPlayerOpen(source); media.onPlayerOpen(source);
manager_.updatePlayerInfoNoRecord( manager.updatePlayerInfoNoRecord(
source, event.ticksMillis, 'render_id', event.renderer); source, event.ticksMillis, 'render_id', event.renderer);
manager_.updatePlayerInfoNoRecord( manager.updatePlayerInfoNoRecord(
source, event.ticksMillis, 'player_id', event.player); source, event.ticksMillis, 'player_id', event.player);
var propertyCount = 0; var propertyCount = 0;
...@@ -85,19 +173,23 @@ var media = (function() { ...@@ -85,19 +173,23 @@ var media = (function() {
key === 'buffer_end' || key === 'buffer_end' ||
key === 'buffer_current' || key === 'buffer_current' ||
key === 'is_downloading_data') { key === 'is_downloading_data') {
manager_.updatePlayerInfoNoRecord( manager.updatePlayerInfoNoRecord(
source, event.ticksMillis, key, value); source, event.ticksMillis, key, value);
} else { } else {
manager_.updatePlayerInfo(source, event.ticksMillis, key, value); manager.updatePlayerInfo(source, event.ticksMillis, key, value);
} }
propertyCount += 1; propertyCount += 1;
}); });
if (propertyCount === 0) { if (propertyCount === 0) {
manager_.updatePlayerInfo( manager.updatePlayerInfo(
source, event.ticksMillis, 'EVENT', event.type); source, event.ticksMillis, 'EVENT', event.type);
} }
}; };
// |chrome| is not defined during tests.
if (window.chrome && window.chrome.send) {
chrome.send('getEverything');
}
return media; return media;
}()); }());
...@@ -18,6 +18,8 @@ table { ...@@ -18,6 +18,8 @@ table {
} }
td { td {
border: 1px solid black; border: 1px solid black;
word-wrap: break-word;
max-width: 200px;
} }
thead { thead {
color: rgb(50,50,50); color: rgb(50,50,50);
...@@ -43,7 +45,6 @@ h3 { ...@@ -43,7 +45,6 @@ h3 {
padding: 0; padding: 0;
padding-left: 25px; padding-left: 25px;
margin: 0; margin: 0;
max-height: 100%;
} }
#list-wrapper { #list-wrapper {
...@@ -52,7 +53,6 @@ h3 { ...@@ -52,7 +53,6 @@ h3 {
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: flex-start;
align-content: stretch; align-content: stretch;
height: 100%;
} }
#player-list-wrapper, #player-list-wrapper,
...@@ -89,3 +89,7 @@ h3 { ...@@ -89,3 +89,7 @@ h3 {
#log-wrapper > thead { #log-wrapper > thead {
position: fixed; position: fixed;
} }
#graphs li {
list-style-type: none;
}
...@@ -9,6 +9,7 @@ found in the LICENSE file. ...@@ -9,6 +9,7 @@ found in the LICENSE file.
<meta charset="utf-8"> <meta charset="utf-8">
<title i18n-content="Media Internals"></title> <title i18n-content="Media Internals"></title>
<link rel="stylesheet" href="media_internals.css"> <link rel="stylesheet" href="media_internals.css">
<script src="chrome://resources/js/cr.js"></script>
</head> </head>
<body> <body>
...@@ -32,6 +33,7 @@ found in the LICENSE file. ...@@ -32,6 +33,7 @@ found in the LICENSE file.
</tr> </tr>
</thead> </thead>
</table> </table>
<ul id="graphs"></ul>
</div> </div>
<div id="log-wrapper"> <div id="log-wrapper">
<h2> <h2>
...@@ -45,8 +47,7 @@ found in the LICENSE file. ...@@ -45,8 +47,7 @@ found in the LICENSE file.
<td>Value</td> <td>Value</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody></tbody>
</tbody>
</table> </table>
</div> </div>
</div> </div>
......
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
var media = {}; var media = {};
<include src="main.js"/>
<include src="util.js"/> <include src="util.js"/>
<include src="../cache_entry.js"/>
<include src="../disjoint_range_set.js"/>
<include src="player_info.js"/> <include src="player_info.js"/>
<include src="manager.js"/> <include src="manager.js"/>
<include src="client_renderer.js"/> <include src="client_renderer.js"/>
<include src="main.js"/>
media.initialize(new Manager(new ClientRenderer())); media.initialize(new Manager(new ClientRenderer()));
...@@ -775,6 +775,7 @@ ...@@ -775,6 +775,7 @@
'../ui/snapshot/snapshot.gyp:snapshot', '../ui/snapshot/snapshot.gyp:snapshot',
'../ui/ui.gyp:shell_dialogs', '../ui/ui.gyp:shell_dialogs',
'../ui/ui.gyp:ui', '../ui/ui.gyp:ui',
'../ui/ui.gyp:ui_resources',
'../webkit/renderer/webkit_renderer.gyp:webkit_renderer', '../webkit/renderer/webkit_renderer.gyp:webkit_renderer',
'../webkit/support/webkit_support.gyp:glue', '../webkit/support/webkit_support.gyp:glue',
'../webkit/support/webkit_support.gyp:glue_child', '../webkit/support/webkit_support.gyp:glue_child',
......
...@@ -7,6 +7,8 @@ found in the LICENSE file. ...@@ -7,6 +7,8 @@ found in the LICENSE file.
<html> <html>
<body> <body>
<script> <script>
window.chrome = {};
window.setUp = function() { window.setUp = function() {
var doNothing = function() {}; var doNothing = function() {};
var mockClientRenderer = { var mockClientRenderer = {
......
...@@ -7,6 +7,8 @@ found in the LICENSE file. ...@@ -7,6 +7,8 @@ found in the LICENSE file.
<html> <html>
<body> <body>
<script> <script>
window.chrome = {};
var doNothing = function() {}; var doNothing = function() {};
var emptyClientRenderer = { var emptyClientRenderer = {
......
...@@ -7,6 +7,8 @@ found in the LICENSE file. ...@@ -7,6 +7,8 @@ found in the LICENSE file.
<html> <html>
<body> <body>
<script> <script>
window.chrome = {};
window.setUp = function() { window.setUp = function() {
window.pi = new PlayerInfo('example_id'); window.pi = new PlayerInfo('example_id');
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "content/test/content_browser_test.h" #include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h" #include "content/test/content_browser_test_utils.h"
#include "grit/content_resources.h" #include "grit/content_resources.h"
#include "grit/webui_resources.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
namespace content { namespace content {
...@@ -32,6 +33,7 @@ class WebUIResourceBrowserTest : public ContentBrowserTest { ...@@ -32,6 +33,7 @@ class WebUIResourceBrowserTest : public ContentBrowserTest {
} }
void RunMediaInternalsTest(const base::FilePath::CharType* file) { void RunMediaInternalsTest(const base::FilePath::CharType* file) {
AddLibrary(IDR_WEBUI_JS_CR);
AddLibrary(IDR_MEDIA_INTERNALS_NEW_JS); AddLibrary(IDR_MEDIA_INTERNALS_NEW_JS);
base::FilePath path; base::FilePath path;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment