blob: b893158fd953e3db1d582e860ad96605e84ee0cd [file] [log] [blame]
/** Convert chrome tabs API to promise */
const chromeTabs = {
get: function(tabId) {
return new Promise(function(resolve) {
chrome.tabs.get(tabId, resolve);
});
},
sendMessage: function(tabId, message, options) {
return new Promise(function(resolve) {
chrome.tabs.sendMessage(tabId, message, options, resolve);
});
},
};
class TaskMonitor {
constructor() {
// Bind the callback
this._updated = this._updated.bind(this);
this._records = [];
}
bind() {
chrome.processes.onUpdated.addListener(this._updated);
}
unbind() {
chrome.processes.onUpdated.removeListener(this._updated);
}
_updated(processes) {
// Structure to hold synthesized data
const data = {
timestamp: Date.now(),
processes: [],
tabInfo: [],
};
// Produce a set of tabId's to populate data.tabInfo in a separate loop
const tabset = new Set();
// Only take a subset of the process data
for (const process of Object.values(processes)) {
// Skip processes that don't consume CPU
if (process.cpu == 0) {
continue;
}
// Only take a subset of the data
const currProcess = {
pid: process.osProcessId,
network: process.network,
cpu: process.cpu,
tasks: [],
};
// Populate process info with 'tabId' and 'title' information
for (const task of Object.values(process.tasks)) {
if ('tabId' in task) {
tabset.add(task.tabId);
currProcess.tasks.push({
tabId: task.tabId,
title: task.title,
});
} else {
if ('title' in task) {
currProcess.tasks.push({title: task.title});
}
}
}
data.processes.push(currProcess);
}
// Populate data.tabInfo with unique tabId's
for (const tabId of tabset) {
data.tabInfo.push({tabId: tabId});
}
const promises = [];
// Record url, audio, muted, and video count
// information per currently open tab
for (const tabInfo of data.tabInfo) {
promises.push(
chromeTabs.get(tabInfo.tabId).then((tab) => {
tabInfo.title = tab.title;
tabInfo.url = tab.url;
tabInfo.audio_played = !!tab.audible;
tabInfo.muted = tab.mutedInfo.muted;
})
);
promises.push(
chromeTabs.sendMessage(tabInfo.tabId, 'numberOfVideosPlaying')
.then((n) => {
if (typeof n === 'undefined') {
tabInfo.videos_playing = 0;
return;
} else {
tabInfo.videos_playing = n;
}
})
);
}
Promise.all(promises).finally(() => {
this._records.push(data);
if (this._records.length >= 1) {
this._send();
}
});
}
_send() {
const formData = new FormData();
this._records.forEach(function(record, index) {
formData.append(index, JSON.stringify(record));
});
this._records.length = 0;
const url = 'http://localhost:8001/task-monitor';
const req = new XMLHttpRequest();
req.open('POST', url, true);
req.send(formData);
}
}
this.task_monitor = new TaskMonitor();