| /** 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(); |