178 lines
5.8 KiB
JavaScript
178 lines
5.8 KiB
JavaScript
// Derived from Chromium WebRTC Internals Dashboard - see Acknowledgements for full license details
|
|
|
|
import {$} from './util.js';
|
|
const USER_MEDIA_TAB_ID = 'user-media-tab-id';
|
|
|
|
/**
|
|
* A helper function for appending a child element to |parent|.
|
|
*
|
|
* @param {!Element} parent The parent element.
|
|
* @param {string} tag The child element tag.
|
|
* @param {string} text The textContent of the new DIV.
|
|
* @return {!Element} the new DIV element.
|
|
*/
|
|
function appendChildWithText(parent, tag, text) {
|
|
const child = document.createElement(tag);
|
|
child.textContent = text;
|
|
parent.appendChild(child);
|
|
return child;
|
|
}
|
|
|
|
export class UserMediaTable {
|
|
/**
|
|
* @param {Object} tabView the TabView object to add the user media tab to.
|
|
*/
|
|
constructor(tabView) {
|
|
this.tabView = tabView;
|
|
}
|
|
|
|
/**
|
|
* Populate the tab view with a getUserMedia/getDisplayMedia tab.
|
|
*/
|
|
createTab() {
|
|
const container = this.tabView.addTab(USER_MEDIA_TAB_ID,
|
|
'getUserMedia/getDisplayMedia');
|
|
// Create the filter input field and label.
|
|
appendChildWithText(container, 'label', 'Filter by origin including ');
|
|
const input = document.createElement('input');
|
|
input.size = 30;
|
|
input.oninput = this.filterUserMedia.bind(this);
|
|
container.appendChild(input);
|
|
}
|
|
|
|
/**
|
|
* Apply a filter to the user media table.
|
|
* @param event InputEvent from the filter input field.
|
|
* @private
|
|
*/
|
|
filterUserMedia(event) {
|
|
const filter = event.target.value;
|
|
const requests = $(USER_MEDIA_TAB_ID).childNodes;
|
|
for (let i = 0; i < requests.length; ++i) {
|
|
if (!requests[i]['data-origin']) {
|
|
continue;
|
|
}
|
|
if (requests[i]['data-origin'].includes(filter)) {
|
|
requests[i].style.display = 'block';
|
|
} else {
|
|
requests[i].style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a getUserMedia/getDisplayMedia request.
|
|
* @param {!Object} data The object containing rid {number}, pid {number},
|
|
* origin {string}, request_id {number}, request_type {string},
|
|
* audio {string}, video {string}.
|
|
*/
|
|
addMedia(data) {
|
|
if (!$(USER_MEDIA_TAB_ID)) {
|
|
this.createTab();
|
|
}
|
|
|
|
const requestDiv = document.createElement('div');
|
|
requestDiv.className = 'user-media-request-div-class';
|
|
requestDiv.id = ['gum', data.rid, data.pid, data.request_id].join('-');
|
|
requestDiv['data-rid'] = data.rid;
|
|
requestDiv['data-origin'] = data.origin;
|
|
// Insert new getUserMedia calls at the top.
|
|
$(USER_MEDIA_TAB_ID).insertBefore(requestDiv,
|
|
$(USER_MEDIA_TAB_ID).firstChild);
|
|
|
|
appendChildWithText(requestDiv, 'div', 'Caller origin: ' + data.origin);
|
|
appendChildWithText(requestDiv, 'div', 'Caller process id: ' + data.pid);
|
|
|
|
const el = appendChildWithText(requestDiv, 'span',
|
|
data.request_type + ' call');
|
|
el.style.fontWeight = 'bold';
|
|
appendChildWithText(el, 'div', 'Time: ' +
|
|
(new Date(data.timestamp).toTimeString()))
|
|
.style.fontWeight = 'normal';
|
|
if (data.audio !== undefined) {
|
|
appendChildWithText(el, 'div', 'Audio constraints: ' +
|
|
(data.audio || 'true'))
|
|
.style.fontWeight = 'normal';
|
|
}
|
|
if (data.video !== undefined) {
|
|
appendChildWithText(el, 'div', 'Video constraints: ' +
|
|
(data.video || 'true'))
|
|
.style.fontWeight = 'normal';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update a getUserMedia/getDisplayMedia request with a result or error.
|
|
*
|
|
* @param {!Object} data The object containing rid {number}, pid {number},
|
|
* request_id {number}, request_type {string}.
|
|
* For results there is also the
|
|
* stream_id {string}, audio_track_info {string} and
|
|
* video_track_info {string}.
|
|
* For errors the error {string} and
|
|
* error_message {string} fields are set.
|
|
*/
|
|
updateMedia(data) {
|
|
if (!$(USER_MEDIA_TAB_ID)) {
|
|
this.createTab();
|
|
}
|
|
|
|
const requestDiv = document.getElementById(
|
|
['gum', data.rid, data.pid, data.request_id].join('-'));
|
|
if (!requestDiv) {
|
|
console.error('Could not update ' + data.request_type + ' request', data);
|
|
return;
|
|
}
|
|
|
|
if (data.error) {
|
|
const el = appendChildWithText(requestDiv, 'span', 'Error');
|
|
el.style.fontWeight = 'bold';
|
|
appendChildWithText(el, 'div', 'Time: ' +
|
|
(new Date(data.timestamp).toTimeString()))
|
|
.style.fontWeight = 'normal';
|
|
appendChildWithText(el, 'div', 'Error: ' + data.error)
|
|
.style.fontWeight = 'normal';
|
|
appendChildWithText(el, 'div', 'Error message: ' + data.error_message)
|
|
.style.fontWeight = 'normal';
|
|
return;
|
|
}
|
|
|
|
const el = appendChildWithText(requestDiv, 'span',
|
|
data.request_type + ' result');
|
|
el.style.fontWeight = 'bold';
|
|
appendChildWithText(el, 'div', 'Time: ' +
|
|
(new Date(data.timestamp).toTimeString()))
|
|
.style.fontWeight = 'normal';
|
|
appendChildWithText(el, 'div', 'Stream id: ' + data.stream_id)
|
|
.style.fontWeight = 'normal';
|
|
if (data.audio_track_info) {
|
|
appendChildWithText(el, 'div', 'Audio track: ' + data.audio_track_info)
|
|
.style.fontWeight = 'normal';
|
|
}
|
|
if (data.video_track_info) {
|
|
appendChildWithText(el, 'div', 'Video track: ' + data.video_track_info)
|
|
.style.fontWeight = 'normal';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the getUserMedia/getDisplayMedia requests from the specified |rid|.
|
|
*
|
|
* @param {!Object} data The object containing rid {number}, the render id.
|
|
*/
|
|
removeMediaForRenderer(data) {
|
|
const requests = $(USER_MEDIA_TAB_ID).childNodes;
|
|
for (let i = 0; i < requests.length; ++i) {
|
|
if (!requests[i]['data-origin']) {
|
|
continue;
|
|
}
|
|
if (requests[i]['data-rid'] === data.rid) {
|
|
$(USER_MEDIA_TAB_ID).removeChild(requests[i]);
|
|
}
|
|
}
|
|
// Remove the tab when only the search field and its label are left.
|
|
if ($(USER_MEDIA_TAB_ID).childNodes.length === 2) {
|
|
this.tabView.removeTab(USER_MEDIA_TAB_ID);
|
|
}
|
|
}
|
|
}
|