blob: 198c2337b4944258d995b0cd96a4b24ca19c85a7 [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {$} from 'chrome://resources/js/util.js';
import {PlayerInfo} from './player_info.js';
import {objectForEach} from './util.js';
/**
* @fileoverview Keeps track of all the existing PlayerInfo and
* audio stream objects and is the entry-point for messages from the backend.
*
* The events captured by Manager (add, remove, update) are relayed
* to the clientRenderer which it can choose to use to modify the UI.
*/
export class Manager {
constructor(clientRenderer) {
this.players_ = {};
this.audioInfo_ = {};
this.audioComponents_ = [];
this.clientRenderer_ = clientRenderer;
const copyAllPlayerButton = $('copy-all-player-button');
const copyAllAudioButton = $('copy-all-audio-button');
const hidePlayersButton = $('hide-players-button');
// In tests we may not have these buttons.
if (copyAllPlayerButton) {
copyAllPlayerButton.onclick = function() {
this.clientRenderer_.renderClipboard(
JSON.stringify(this.players_, null, 2));
}.bind(this);
}
if (copyAllAudioButton) {
copyAllAudioButton.onclick = function() {
this.clientRenderer_.renderClipboard(
JSON.stringify(this.audioInfo_, null, 2) + '\n\n' +
JSON.stringify(this.audioComponents_, null, 2));
}.bind(this);
}
if (hidePlayersButton) {
hidePlayersButton.onclick = this.hidePlayers_.bind(this);
}
}
/**
* Updates the audio focus state.
* @param sessions A list of media sessions that contain the current state.
*/
updateAudioFocusSessions(sessions) {
this.clientRenderer_.audioFocusSessionUpdated(sessions);
}
/**
* Updates the registered CDM list.
* @param cdms A list of registered Content Decryption Modules.
*/
updateRegisteredCdms(cdms) {
this.clientRenderer_.updateRegisteredCdms(cdms);
}
/**
* Updates the general audio information.
* @param audioInfo The map of information.
*/
updateGeneralAudioInformation(audioInfo) {
this.audioInfo_ = audioInfo;
this.clientRenderer_.generalAudioInformationSet(this.audioInfo_);
}
/**
* Updates an audio-component.
* @param componentType Integer AudioComponent enum value; must match values
* from the AudioLogFactory::AudioComponent enum.
* @param componentId The unique-id of the audio-component.
* @param componentData The actual component data dictionary.
*/
updateAudioComponent(componentType, componentId, componentData) {
if (!(componentType in this.audioComponents_)) {
this.audioComponents_[componentType] = {};
}
if (!(componentId in this.audioComponents_[componentType])) {
this.audioComponents_[componentType][componentId] = componentData;
} else {
for (const key in componentData) {
this.audioComponents_[componentType][componentId][key] =
componentData[key];
}
}
this.clientRenderer_.audioComponentAdded(
componentType, this.audioComponents_[componentType]);
}
/**
* Removes an audio-stream from the manager.
* @param id The unique-id of the audio-stream.
*/
removeAudioComponent(componentType, componentId) {
if (!(componentType in this.audioComponents_) ||
!(componentId in this.audioComponents_[componentType])) {
return;
}
delete this.audioComponents_[componentType][componentId];
this.clientRenderer_.audioComponentRemoved(
componentType, this.audioComponents_[componentType]);
}
/**
* Adds a player to the list of players to manage.
*/
addPlayer(id) {
if (this.players_[id]) {
return;
}
// Make the PlayerProperty and add it to the mapping
this.players_[id] = new PlayerInfo(id);
this.clientRenderer_.playerAdded(this.players_, this.players_[id]);
}
/**
* Attempts to remove a player from the UI.
* @param id The ID of the player to remove.
*/
removePlayer(id) {
const playerRemoved = this.players_[id];
delete this.players_[id];
this.clientRenderer_.playerRemoved(this.players_, playerRemoved);
}
hidePlayers_() {
objectForEach(this.players_, function(playerInfo, id) {
this.removePlayer(id);
}, this);
}
updatePlayerInfoNoRecord(id, timestamp, key, value) {
if (!this.players_[id]) {
console.error('[updatePlayerInfo] Id ' + id + ' does not exist');
return;
}
this.players_[id].addPropertyNoRecord(timestamp, key, value);
this.clientRenderer_.playerUpdated(
this.players_, this.players_[id], key, value);
}
/**
*
* @param id The unique ID that identifies the player to be updated.
* @param timestamp The timestamp of when the change occurred. This
* timestamp is *not* normalized.
* @param key The name of the property to be added/changed.
* @param value The value of the property.
*/
updatePlayerInfo(id, timestamp, key, value) {
if (!this.players_[id]) {
console.error('[updatePlayerInfo] Id ' + id + ' does not exist');
return;
}
this.players_[id].addProperty(timestamp, key, value);
this.clientRenderer_.playerUpdated(
this.players_, this.players_[id], key, value);
}
parseVideoCaptureFormat_(format) {
/**
* Example:
*
* format:
* "(160x120)@30.000fps, pixel format: PIXEL_FORMAT_I420, storage: CPU"
*
* formatDict:
* {'resolution':'1280x720', 'fps': '30.00', "storage: "CPU" }
*/
const parts = format.split(', ');
const formatDict = {};
for (const i in parts) {
let kv = parts[i].split(': ');
if (kv.length === 2) {
if (kv[0] === 'pixel format') {
// The camera does not actually output I420,
// so this info is misleading.
continue;
}
formatDict[kv[0]] = kv[1];
} else {
kv = parts[i].split('@');
if (kv.length === 2) {
formatDict['resolution'] = kv[0].replace(/[)(]/g, '');
// Round down the FPS to 2 decimals.
formatDict['fps'] = parseFloat(kv[1].replace(/fps$/, '')).toFixed(2);
}
}
}
return formatDict;
}
updateVideoCaptureCapabilities(videoCaptureCapabilities) {
// Parse the video formats to be structured for the table.
for (const i in videoCaptureCapabilities) {
for (const j in videoCaptureCapabilities[i]['formats']) {
videoCaptureCapabilities[i]['formats'][j] =
this.parseVideoCaptureFormat_(
videoCaptureCapabilities[i]['formats'][j]);
}
videoCaptureCapabilities[i]['controlSupport'] =
videoCaptureCapabilities[i]['controlSupport'].join(' ') || 'N/A';
}
// The keys of each device to be shown in order of appearance.
const videoCaptureDeviceKeys =
['name', 'formats', 'captureApi', 'controlSupport', 'id'];
this.clientRenderer_.redrawVideoCaptureCapabilities(
videoCaptureCapabilities, videoCaptureDeviceKeys);
}
}
// Exporting the class on window for tests.
window.Manager = Manager;