Commit a44d2ea8 authored by thestig@chromium.org's avatar thestig@chromium.org

Delete the WebUI implementation of the task manager.

It is no longer used.

BUG=

Review URL: https://codereview.chromium.org/101013004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243834 0039d316-1c4b-4281-b951-d872f2087c98
parent d86263dc
...@@ -282,18 +282,6 @@ ...@@ -282,18 +282,6 @@
<include name="IDR_WEBRTC_LOGS_JS" file="resources\media\webrtc_logs.js" type="BINDATA" /> <include name="IDR_WEBRTC_LOGS_JS" file="resources\media\webrtc_logs.js" type="BINDATA" />
</if> </if>
<include name="IDR_WEBSTORE_MANIFEST" file="resources\webstore_app\manifest.json" type="BINDATA" /> <include name="IDR_WEBSTORE_MANIFEST" file="resources\webstore_app\manifest.json" type="BINDATA" />
<if expr="pp_ifdef('use_ash')">
<include name="IDR_TASK_MANAGER_HTML" file="resources\task_manager\main.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_TASK_MANAGER_COMMANDS_JS" file="resources\task_manager\commands.js" type="BINDATA" />
<!-- The following defines.js uses flattenhtml feature to remove the platform-dependent code at compile-time. -->
<include name="IDR_TASK_MANAGER_DEFINES_JS" file="resources\task_manager\defines.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_TASK_MANAGER_INCLUDES_JS" file="resources\task_manager\includes.js" type="BINDATA" />
<include name="IDR_TASK_MANAGER_PRELOAD_JS" file="resources\task_manager\preload.js" type="BINDATA" />
<!-- The following main.js uses flattenhtml feature to remove the platform-dependent code at complie-time. -->
<include name="IDR_TASK_MANAGER_JS" file="resources\task_manager\main.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_TASK_MANAGER_MEASURE_TIME_JS" file="resources\task_manager\measure_time.js" type="BINDATA" />
<include name="IDR_TASK_MANAGER_MEASURE_TIME_END_JS" file="resources\task_manager\measure_time_end.js" type="BINDATA" />
</if>
<include name="IDR_GAIA_AUTH_MANIFEST" file="resources\gaia_auth\manifest.json" type="BINDATA" /> <include name="IDR_GAIA_AUTH_MANIFEST" file="resources\gaia_auth\manifest.json" type="BINDATA" />
<include name="IDR_GAIA_AUTH_KEYBOARD_MANIFEST" file="resources\gaia_auth\manifest_keyboard.json" type="BINDATA" /> <include name="IDR_GAIA_AUTH_KEYBOARD_MANIFEST" file="resources\gaia_auth\manifest_keyboard.json" type="BINDATA" />
<include name="IDR_GAIA_AUTH_SAML_MANIFEST" file="resources\gaia_auth\manifest_saml.json" type="BINDATA" /> <include name="IDR_GAIA_AUTH_SAML_MANIFEST" file="resources\gaia_auth\manifest_saml.json" type="BINDATA" />
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
TaskManagerCommands = {
/**
* Sends commands to kill selected processes.
*/
killSelectedProcesses: function(uniqueIds) {
chrome.send('killProcesses', uniqueIds);
},
/**
* Sends command to initiate resource inspection.
*/
inspect: function(uniqueId) {
chrome.send('inspect', [uniqueId]);
},
/**
* Sends command to open about memory tab.
*/
openAboutMemory: function() {
chrome.send('openAboutMemory');
},
/**
* Sends command to disable taskmanager model.
*/
disableTaskManager: function() {
chrome.send('disableTaskManager');
},
/**
* Sends command to enable taskmanager model.
*/
enableTaskManager: function() {
chrome.send('enableTaskManager');
},
/**
* Sends command to activate a page.
*/
activatePage: function(uniqueId) {
chrome.send('activatePage', [uniqueId]);
},
/**
* Sends command to enable or disable the given columns to update the data.
*/
setUpdateColumn: function(columnId, isEnabled) {
chrome.send('setUpdateColumn', [columnId, isEnabled]);
// The 'title' column contains the icon.
if (columnId == 'title')
chrome.send('setUpdateColumn', ['icon', isEnabled]);
}
};
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Whether task manager shows 'Private Memory' instead of 'Phsical Memory'.
* @const
*/
var USE_PRIVATE_MEM = false;
// <if expr="(is_linux or pp_ifdef('chromeos'))">
// On Linux and ChromeOS, this is true because calculating Phsical Memory is
// slow.
USE_PRIVATE_MEM = true;
// </if>
/*
* Default columns (column_id, label_id, width, is_default)
* @const
*/
var DEFAULT_COLUMNS = [
['title', 'taskColumn', 300, true],
['profileName', 'profileNameColumn', 120, false],
['physicalMemory', 'physicalMemColumn', 80, !USE_PRIVATE_MEM],
['sharedMemory', 'sharedMemColumn', 80, false],
['privateMemory', 'privateMemColumn', 80, USE_PRIVATE_MEM],
['cpuUsage', 'cpuColumn', 80, true],
['networkUsage', 'netColumn', 85, true],
['processId', 'processIDColumn', 100, false],
['webCoreImageCacheSize', 'webcoreImageCacheColumn', 120, false],
['webCoreScriptsCacheSize', 'webcoreScriptsCacheColumn', 120, false],
['webCoreCSSCacheSize', 'webcoreCSSCacheColumn', 120, false],
['fps', 'fpsColumn', 50, true],
['videoMemory', 'videoMemoryColumn', 80, false],
['sqliteMemoryUsed', 'sqliteMemoryUsedColumn', 80, false],
['goatsTeleported', 'goatsTeleportedColumn', 80, false],
['v8MemoryAllocatedSize', 'javascriptMemoryAllocatedColumn', 120, false],
];
/*
* Height of each tasks. It is 20px, which is also defined in CSS.
* @const
*/
var HEIGHT_OF_TASK = 20;
var COMMAND_CONTEXTMENU_COLUMN_PREFIX = 'columnContextMenu';
var COMMAND_CONTEXTMENU_TABLE_PREFIX = 'tableContextMenu';
var ENABLED_COLUMNS_KEY = 'enabledColumns';
var DEFAULT_SORT_COLUMN = 'cpuUsage';
var DEFAULT_SORT_DIRECTION = 'desc';
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This script includes additional resources via document.write(). Hence, it
// must be a separate script file loaded before other scripts which would
// reference the resources.
var css = [
'chrome_shared.css',
'list.css',
'table.css',
'menu.css',
];
var script = [
'load_time_data.js',
'i18n_template_no_process.js',
'event_tracker.js',
'util.js',
'cr.js',
'cr/ui.js',
'cr/event_target.js',
'cr/ui/array_data_model.js',
'cr/ui/list_item.js',
'cr/ui/list_selection_model.js',
'cr/ui/list_single_selection_model.js',
'cr/ui/list_selection_controller.js',
'cr/ui/list.js',
'cr/ui/splitter.js',
'cr/ui/table/table_splitter.js',
'cr/ui/touch_handler.js',
'cr/ui/table/table_column.js',
'cr/ui/table/table_column_model.js',
'cr/ui/table/table_header.js',
'cr/ui/table/table_list.js',
'cr/ui/table.js',
'cr/ui/grid.js',
];
var scriptDelayed = [
'cr/ui/command.js',
'cr/ui/position_util.js',
'cr/ui/menu_item.js',
'cr/ui/menu.js',
'cr/ui/context_menu_handler.js',
];
var loadDelayedIncludes;
(function() {
// Switch to 'test harness' mode when loading from a file url.
var isHarness = document.location.protocol == 'file:';
// In test harness mode we load resources from relative dirs.
var prefix = isHarness ? './shared/' : 'chrome://resources/';
for (var i = 0; i < css.length; i++) {
document.write('<link href="' + prefix + 'css/' + css[i] +
'" rel="stylesheet"></link>');
}
for (var i = 0; i < script.length; i++) {
document.write('<script src="' + prefix + 'js/' + script[i] +
'"><\/script>');
}
/**
* Loads delayed scripts.
* This function is called by TaskManager::initalize() in main.js.
*/
loadDelayedIncludes = function(taskmanager) {
// Number of remaining scripts to load.
var remain = scriptDelayed.length;
// Waits for initialization of task manager.
for (var i = 0; i < scriptDelayed.length; i++) {
var s = document.createElement('script');
s.onload = function(e) {
if (!--remain)
taskmanager.delayedInitialize();
};
s.src = prefix + 'js/' + scriptDelayed[i];
document.head.appendChild(s);
}
};
})();
<!DOCTYPE HTML>
<!--
-- Copyright (c) 2012 The Chromium Authors. All rights reserved.
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.
-->
<html i18n-values="dir:textdirection;">
<head>
<meta charset="utf-8">
<title i18n-content="title"></title>
<script src="measure_time.js"></script>
<script src="commands.js"></script>
<script src="defines.js"></script>
<script src="preload.js"></script>
<script src="includes.js"></script>
<script src="main.js"></script>
<script src="chrome://tasks/strings.js"></script>
<!-- For accurate load performance tracking
place all scripts above this line -->
<script src="measure_time_end.js"></script>
<link rel="stylesheet" href="task_manager.css">
</head>
<body>
<div class="dialog-body">
<div class="list-container">
<div class="detail-table"></div>
</div>
</div>
<div class="dialog-footer">
<div class="footer-left-container">
<a href="#" id="about-memory-link" i18n-content="aboutMemoryLink"></a>
</div>
<div class="footer-right-container">
<button id="kill-process" i18n-content="killButton" disabled></button>
<if expr="pp_ifdef('chromeos')">
<button id="close-window" i18n-content="closeWindow"></button>
</if>
</div>
</div>
</body>
</html>
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** @constructor */
function TaskManager() { }
cr.addSingletonGetter(TaskManager);
TaskManager.prototype = {
/**
* Handle window close.
* @this
*/
onClose: function() {
if (!this.disabled_) {
this.disabled_ = true;
commands.disableTaskManager();
}
},
/**
* Handles selection changes.
* This is also called when data of tasks are refreshed, even if selection
* has not been changed.
* @this
*/
onSelectionChange: function() {
var sm = this.selectionModel_;
var dm = this.dataModel_;
var selectedIndexes = sm.selectedIndexes;
var isEndProcessEnabled = true;
if (selectedIndexes.length == 0)
isEndProcessEnabled = false;
for (var i = 0; i < selectedIndexes.length; i++) {
var index = selectedIndexes[i];
var task = dm.item(index);
if (task['type'] == 'BROWSER')
isEndProcessEnabled = false;
}
if (this.isEndProcessEnabled_ != isEndProcessEnabled) {
if (isEndProcessEnabled)
$('kill-process').removeAttribute('disabled');
else
$('kill-process').setAttribute('disabled', 'true');
this.isEndProcessEnabled_ = isEndProcessEnabled;
}
},
/**
* Closes taskmanager dialog.
* After this function is called, onClose() will be called.
* @this
*/
close: function() {
window.close();
},
/**
* Sends commands to kill selected processes.
* @this
*/
killSelectedProcesses: function() {
var selectedIndexes = this.selectionModel_.selectedIndexes;
var dm = this.dataModel_;
var uniqueIds = [];
for (var i = 0; i < selectedIndexes.length; i++) {
var index = selectedIndexes[i];
var task = dm.item(index);
uniqueIds.push(task['uniqueId'][0]);
}
commands.killSelectedProcesses(uniqueIds);
},
/**
* Initializes taskmanager.
* @this
*/
initialize: function(dialogDom, opt) {
if (!dialogDom) {
console.log('ERROR: dialogDom is not defined.');
return;
}
measureTime.startInterval('Load.DOM');
this.opt_ = opt;
this.initialized_ = true;
this.elementsCache_ = {};
this.dialogDom_ = dialogDom;
this.document_ = dialogDom.ownerDocument;
this.localized_column_ = [];
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
var columnLabelId = DEFAULT_COLUMNS[i][1];
this.localized_column_[i] = loadTimeData.getString(columnLabelId);
}
this.initElements_();
this.initColumnModel_();
this.selectionModel_ = new cr.ui.ListSelectionModel();
this.dataModel_ = new cr.ui.ArrayDataModel([]);
this.selectionModel_.addEventListener('change',
this.onSelectionChange.bind(this));
// Initializes compare functions for column sort.
var dm = this.dataModel_;
// List of columns to sort by its numerical value as opposed to the
// formatted value, e.g., 20480 vs. 20KB.
var COLUMNS_SORTED_BY_VALUE = [
'cpuUsage', 'physicalMemory', 'sharedMemory', 'privateMemory',
'networkUsage', 'webCoreImageCacheSize', 'webCoreScriptsCacheSize',
'webCoreCSSCacheSize', 'fps', 'videoMemory', 'sqliteMemoryUsed',
'goatsTeleported', 'v8MemoryAllocatedSize'];
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
var columnId = DEFAULT_COLUMNS[i][0];
var compareFunc = (function() {
var columnIdToSort = columnId;
if (COLUMNS_SORTED_BY_VALUE.indexOf(columnId) != -1)
columnIdToSort += 'Value';
return function(a, b) {
var aValues = a[columnIdToSort];
var bValues = b[columnIdToSort];
var aValue = aValues && aValues[0] || 0;
var bvalue = bValues && bValues[0] || 0;
return dm.defaultValuesCompareFunction(aValue, bvalue);
};
})();
dm.setCompareFunction(columnId, compareFunc);
}
if (isColumnEnabled(DEFAULT_SORT_COLUMN))
dm.sort(DEFAULT_SORT_COLUMN, DEFAULT_SORT_DIRECTION);
this.initTable_();
commands.enableTaskManager();
// Populate the static localized strings.
i18nTemplate.process(this.document_, loadTimeData);
measureTime.recordInterval('Load.DOM');
measureTime.recordInterval('Load.Total');
loadDelayedIncludes(this);
},
/**
* Initializes the visibilities and handlers of the elements.
* This method is called by initialize().
* @private
* @this
*/
initElements_: function() {
// <if expr="pp_ifdef('chromeos')">
// The 'close-window' element exists only on ChromeOS.
// This <if ... /if> section is removed while flattening HTML if chrome is
// built as Desktop Chrome.
if (!this.opt_['isShowCloseButton'])
$('close-window').style.display = 'none';
$('close-window').addEventListener('click', this.close.bind(this));
// </if>
$('kill-process').addEventListener('click',
this.killSelectedProcesses.bind(this));
$('about-memory-link').addEventListener('click', commands.openAboutMemory);
},
/**
* Additional initialization of taskmanager. This function is called when
* the loading of delayed scripts finished.
* @this
*/
delayedInitialize: function() {
this.initColumnMenu_();
this.initTableMenu_();
var dm = this.dataModel_;
for (var i = 0; i < dm.length; i++) {
var processId = dm.item(i)['processId'][0];
for (var j = 0; j < DEFAULT_COLUMNS.length; j++) {
var columnId = DEFAULT_COLUMNS[j][0];
var row = dm.item(i)[columnId];
if (!row)
continue;
for (var k = 0; k < row.length; k++) {
var labelId = 'detail-' + columnId + '-pid' + processId + '-' + k;
var label = $(labelId);
// Initialize a context-menu, if the label exists and its context-
// menu is not initialized yet.
if (label && !label.contextMenu)
cr.ui.contextMenuHandler.setContextMenu(label,
this.tableContextMenu_);
}
}
}
this.isFinishedInitDelayed_ = true;
var t = this.table_;
t.redraw();
addEventListener('resize', t.redraw.bind(t));
},
initColumnModel_: function() {
var tableColumns = new Array();
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
var column = DEFAULT_COLUMNS[i];
var columnId = column[0];
if (!isColumnEnabled(columnId))
continue;
tableColumns.push(new cr.ui.table.TableColumn(columnId,
this.localized_column_[i],
column[2]));
}
for (var i = 0; i < tableColumns.length; i++) {
tableColumns[i].renderFunction = this.renderColumn_.bind(this);
}
this.columnModel_ = new cr.ui.table.TableColumnModel(tableColumns);
},
initColumnMenu_: function() {
this.column_menu_commands_ = [];
this.commandsElement_ = this.document_.createElement('commands');
this.document_.body.appendChild(this.commandsElement_);
this.columnSelectContextMenu_ = this.document_.createElement('menu');
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
var column = DEFAULT_COLUMNS[i];
// Creates command element to receive event.
var command = this.document_.createElement('command');
command.id = COMMAND_CONTEXTMENU_COLUMN_PREFIX + '-' + column[0];
cr.ui.Command.decorate(command);
this.column_menu_commands_[command.id] = command;
this.commandsElement_.appendChild(command);
// Creates menuitem element.
var item = this.document_.createElement('menuitem');
item.command = command;
command.menuitem = item;
item.textContent = this.localized_column_[i];
if (isColumnEnabled(column[0]))
item.setAttributeNode(this.document_.createAttribute('checked'));
this.columnSelectContextMenu_.appendChild(item);
}
this.document_.body.appendChild(this.columnSelectContextMenu_);
cr.ui.Menu.decorate(this.columnSelectContextMenu_);
cr.ui.contextMenuHandler.setContextMenu(this.table_.header,
this.columnSelectContextMenu_);
cr.ui.contextMenuHandler.setContextMenu(this.table_.list,
this.columnSelectContextMenu_);
this.document_.addEventListener('command', this.onCommand_.bind(this));
this.document_.addEventListener('canExecute',
this.onCommandCanExecute_.bind(this));
},
initTableMenu_: function() {
this.table_menu_commands_ = [];
this.tableContextMenu_ = this.document_.createElement('menu');
var addMenuItem = function(tm, commandId, string_id) {
// Creates command element to receive event.
var command = tm.document_.createElement('command');
command.id = COMMAND_CONTEXTMENU_TABLE_PREFIX + '-' + commandId;
cr.ui.Command.decorate(command);
tm.table_menu_commands_[command.id] = command;
tm.commandsElement_.appendChild(command);
// Creates menuitem element.
var item = tm.document_.createElement('menuitem');
item.command = command;
command.menuitem = item;
item.textContent = loadTimeData.getString(string_id);
tm.tableContextMenu_.appendChild(item);
};
addMenuItem(this, 'inspect', 'inspect');
addMenuItem(this, 'activate', 'activate');
this.document_.body.appendChild(this.tableContextMenu_);
cr.ui.Menu.decorate(this.tableContextMenu_);
},
initTable_: function() {
if (!this.dataModel_ || !this.selectionModel_ || !this.columnModel_) {
console.log('ERROR: some models are not defined.');
return;
}
this.table_ = this.dialogDom_.querySelector('.detail-table');
cr.ui.Table.decorate(this.table_);
this.table_.dataModel = this.dataModel_;
this.table_.selectionModel = this.selectionModel_;
this.table_.columnModel = this.columnModel_;
// Expands height of row when a process has some tasks.
this.table_.fixedHeight = false;
this.table_.list.addEventListener('contextmenu',
this.onTableContextMenuOpened_.bind(this),
true);
// Sets custom row render function.
this.table_.setRenderFunction(this.getRow_.bind(this));
},
/**
* Returns a list item element of the list. This method trys to reuse the
* cached element, or creates a new element.
* @return {cr.ui.ListItem} list item element which contains the given data.
* @private
* @this
*/
getRow_: function(data, table) {
// Trys to reuse the cached row;
var listItemElement = this.renderRowFromCache_(data, table);
if (listItemElement)
return listItemElement;
// Initializes the cache.
var pid = data['processId'][0];
this.elementsCache_[pid] = {
listItem: null,
cell: [],
icon: [],
columns: {}
};
// Create new row.
return this.renderRow_(data, table);
},
/**
* Returns a list item element with re-using the previous cached element, or
* returns null if failed.
* @return {cr.ui.ListItem} cached un-used element to be reused.
* @private
* @this
*/
renderRowFromCache_: function(data, table) {
var pid = data['processId'][0];
// Checks whether the cache exists or not.
var cache = this.elementsCache_[pid];
if (!cache)
return null;
var listItemElement = cache.listItem;
var cm = table.columnModel;
// Checks whether the number of columns has been changed or not.
if (cache.cachedColumnSize != cm.size)
return null;
// Checks whether the number of childlen tasks has been changed or not.
if (cache.cachedChildSize != data['uniqueId'].length)
return null;
// Updates informations of the task if necessary.
for (var i = 0; i < cm.size; i++) {
var columnId = cm.getId(i);
var columnData = data[columnId];
var oldColumnData = listItemElement.data[columnId];
var columnElements = cache.columns[columnId];
if (!columnData || !oldColumnData || !columnElements)
return null;
// Sets new width of the cell.
var cellElement = cache.cell[i];
cellElement.style.width = cm.getWidth(i) + '%';
for (var j = 0; j < columnData.length; j++) {
// Sets the new text, if the text has been changed.
if (oldColumnData[j] != columnData[j]) {
var textElement = columnElements[j];
textElement.textContent = columnData[j];
}
}
}
// Updates icon of the task if necessary.
var oldIcons = listItemElement.data['icon'];
var newIcons = data['icon'];
if (oldIcons && newIcons) {
for (var j = 0; j < columnData.length; j++) {
var oldIcon = oldIcons[j];
var newIcon = newIcons[j];
if (oldIcon != newIcon) {
var iconElement = cache.icon[j];
iconElement.src = newIcon;
}
}
}
listItemElement.data = data;
// Removes 'selected' and 'lead' attributes.
listItemElement.removeAttribute('selected');
listItemElement.removeAttribute('lead');
return listItemElement;
},
/**
* Create a new list item element.
* @return {cr.ui.ListItem} created new list item element.
* @private
* @this
*/
renderRow_: function(data, table) {
var pid = data['processId'][0];
var cm = table.columnModel;
var listItem = new cr.ui.ListItem({label: ''});
listItem.className = 'table-row';
for (var i = 0; i < cm.size; i++) {
var cell = document.createElement('div');
cell.style.width = cm.getWidth(i) + '%';
cell.className = 'table-row-cell';
cell.id = 'column-' + pid + '-' + cm.getId(i);
cell.appendChild(
cm.getRenderFunction(i).call(null, data, cm.getId(i), table));
listItem.appendChild(cell);
// Stores the cell element to the dictionary.
this.elementsCache_[pid].cell[i] = cell;
}
// Specifies the height of the row. The height of each row is
// 'num_of_tasks * HEIGHT_OF_TASK' px.
listItem.style.height = (data['uniqueId'].length * HEIGHT_OF_TASK) + 'px';
listItem.data = data;
// Stores the list item element, the number of columns and the number of
// childlen.
this.elementsCache_[pid].listItem = listItem;
this.elementsCache_[pid].cachedColumnSize = cm.size;
this.elementsCache_[pid].cachedChildSize = data['uniqueId'].length;
return listItem;
},
/**
* Create a new element of the cell.
* @return {HTMLDIVElement} created cell
* @private
* @this
*/
renderColumn_: function(entry, columnId, table) {
var container = this.document_.createElement('div');
container.className = 'detail-container-' + columnId;
var pid = entry['processId'][0];
var cache = [];
var cacheIcon = [];
if (entry && entry[columnId]) {
container.id = 'detail-container-' + columnId + '-pid' + entry.processId;
for (var i = 0; i < entry[columnId].length; i++) {
var label = document.createElement('div');
if (columnId == 'title') {
// Creates a page title element with icon.
var image = this.document_.createElement('img');
image.className = 'detail-title-image';
image.src = entry['icon'][i];
image.id = 'detail-title-icon-pid' + pid + '-' + i;
label.appendChild(image);
var text = this.document_.createElement('div');
text.className = 'detail-title-text';
text.id = 'detail-title-text-pid' + pid + '-' + i;
text.textContent = entry['title'][i];
label.appendChild(text);
// Chech if the delayed scripts (included in includes.js) have been
// loaded or not. If the delayed scripts ware not loaded yet, a
// context menu could not be initialized. In such case, it will be
// initialized at delayedInitialize() just after loading of delayed
// scripts instead of here.
if (this.isFinishedInitDelayed_)
cr.ui.contextMenuHandler.setContextMenu(label,
this.tableContextMenu_);
label.addEventListener('dblclick', (function(uniqueId) {
commands.activatePage(uniqueId);
}).bind(this, entry['uniqueId'][i]));
label.data = entry;
label.index_in_group = i;
cache[i] = text;
cacheIcon[i] = image;
} else {
label.textContent = entry[columnId][i];
cache[i] = label;
}
label.id = 'detail-' + columnId + '-pid' + pid + '-' + i;
label.className = 'detail-' + columnId + ' pid' + pid;
container.appendChild(label);
}
this.elementsCache_[pid].columns[columnId] = cache;
if (columnId == 'title')
this.elementsCache_[pid].icon = cacheIcon;
}
return container;
},
/**
* Updates the task list with the supplied task.
* @private
* @this
*/
processTaskChange: function(task) {
var dm = this.dataModel_;
var sm = this.selectionModel_;
if (!dm || !sm) return;
this.table_.list.startBatchUpdates();
sm.beginChange();
var type = task.type;
var start = task.start;
var length = task.length;
var tasks = task.tasks;
// We have to store the selected pids and restore them after
// splice(), because it might replace some items but the replaced
// items would lose the selection.
var oldSelectedIndexes = sm.selectedIndexes;
// Create map of selected PIDs.
var selectedPids = {};
for (var i = 0; i < oldSelectedIndexes.length; i++) {
var item = dm.item(oldSelectedIndexes[i]);
if (item) selectedPids[item['processId'][0]] = true;
}
var args = tasks.slice();
args.unshift(start, dm.length);
dm.splice.apply(dm, args);
// Create new array of selected indexes from map of old PIDs.
var newSelectedIndexes = [];
for (var i = 0; i < dm.length; i++) {
if (selectedPids[dm.item(i)['processId'][0]])
newSelectedIndexes.push(i);
}
sm.selectedIndexes = newSelectedIndexes;
var pids = [];
for (var i = 0; i < dm.length; i++) {
pids.push(dm.item(i)['processId'][0]);
}
// Sweeps unused caches, which elements no longer exist on the list.
for (var pid in this.elementsCache_) {
if (pids.indexOf(pid) == -1)
delete this.elementsCache_[pid];
}
sm.endChange();
this.table_.list.endBatchUpdates();
},
/**
* Respond to a command being executed.
* @this
*/
onCommand_: function(event) {
var command = event.command;
var commandId = command.id.split('-', 2);
var mainCommand = commandId[0];
var subCommand = commandId[1];
if (mainCommand == COMMAND_CONTEXTMENU_COLUMN_PREFIX) {
this.onColumnContextMenu_(subCommand, command);
} else if (mainCommand == COMMAND_CONTEXTMENU_TABLE_PREFIX) {
var targetUniqueId = this.currentContextMenuTarget_;
if (!targetUniqueId)
return;
if (subCommand == 'inspect')
commands.inspect(targetUniqueId);
else if (subCommand == 'activate')
commands.activatePage(targetUniqueId);
this.currentContextMenuTarget_ = undefined;
}
},
onCommandCanExecute_: function(event) {
event.canExecute = true;
},
/**
* Store resourceIndex of target resource of context menu, because resource
* will be replaced when it is refreshed.
* @this
*/
onTableContextMenuOpened_: function(e) {
if (!this.isFinishedInitDelayed_)
return;
var mc = this.table_menu_commands_;
var inspectMenuitem =
mc[COMMAND_CONTEXTMENU_TABLE_PREFIX + '-inspect'].menuitem;
var activateMenuitem =
mc[COMMAND_CONTEXTMENU_TABLE_PREFIX + '-activate'].menuitem;
// Disabled by default.
inspectMenuitem.disabled = true;
activateMenuitem.disabled = true;
var target = e.target;
for (;; target = target.parentNode) {
if (!target) return;
var classes = target.classList;
if (classes &&
Array.prototype.indexOf.call(classes, 'detail-title') != -1) break;
}
var indexInGroup = target.index_in_group;
// Sets the uniqueId for current target page under the mouse corsor.
this.currentContextMenuTarget_ = target.data['uniqueId'][indexInGroup];
// Enables if the page can be inspected.
if (target.data['canInspect'][indexInGroup])
inspectMenuitem.disabled = false;
// Enables if the page can be activated.
if (target.data['canActivate'][indexInGroup])
activateMenuitem.disabled = false;
},
onColumnContextMenu_: function(columnId, command) {
var menuitem = command.menuitem;
var checkedItemCount = 0;
var checked = isColumnEnabled(columnId);
// Leaves a item visible when user tries making invisible but it is the
// last one.
var enabledColumns = getEnabledColumns();
for (var id in enabledColumns) {
if (enabledColumns[id])
checkedItemCount++;
}
if (checkedItemCount == 1 && checked)
return;
// Toggles the visibility of the column.
var newChecked = !checked;
menuitem.checked = newChecked;
setColumnEnabled(columnId, newChecked);
this.initColumnModel_();
this.table_.columnModel = this.columnModel_;
this.table_.redraw();
},
};
// |taskmanager| has been declared in preload.js.
taskmanager = TaskManager.getInstance();
function init() {
var params = parseQueryParams(window.location);
var opt = {};
opt['isShowCloseButton'] = params.showclose;
taskmanager.initialize(document.body, opt);
}
document.addEventListener('DOMContentLoaded', init);
document.addEventListener('Close', taskmanager.onClose.bind(taskmanager));
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Utility methods for measuring loading times.
*
* To be included as a first script in main.html
*/
/**
* measureTime class
* @constructor
*/
var measureTime = {
isEnabled: localStorage.measureTimeEnabled,
startInterval: function(name) {
if (this.isEnabled)
console.time(name);
},
recordInterval: function(name) {
if (this.isEnabled)
console.timeEnd(name);
},
};
measureTime.startInterval('Load.Total');
measureTime.startInterval('Load.Script');
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
measureTime.recordInterval('Load.Script');
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Defines global variables.
var commands = TaskManagerCommands;
var taskmanager = undefined; // This will be instantiated in main.js.
/**
* Invoked when a range of items has changed.
* @param {Integer} start The start position of tasks to be changed
* @param {Integer} length The length of tasks to be changed
* @param {Array of task} tasks The array of updated task
*/
function taskChanged(start, length, tasks) {
var task = {type: 'change', start: start, length: length, tasks: tasks};
if (taskmanager) taskmanager.processTaskChange(task);
}
// Cached list of enabled columns to prevent frequent access to localStorage.
var cachedEnabledColumns;
/**
* @return {Dictionary} the dictionary which contains the list of columns and
* whether each column is enabled or not.
*/
function getEnabledColumns() {
// Use the cache after the second time since access to localStorage is slow.
if (cachedEnabledColumns)
return cachedEnabledColumns;
var json = window.localStorage.getItem(ENABLED_COLUMNS_KEY);
try {
cachedEnabledColumns = JSON.parse(json) || {};
} catch (e) {
cachedEnabledColumns = {};
}
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
if (typeof(cachedEnabledColumns[DEFAULT_COLUMNS[i][0]]) == 'undefined')
cachedEnabledColumns[DEFAULT_COLUMNS[i][0]] = DEFAULT_COLUMNS[i][3];
}
return cachedEnabledColumns;
}
/**
* @return {boolean} the given column (at |columnId|) is enabled or not.
* @param {string} columnId The ID of the collumn to be checked.
*/
function isColumnEnabled(columnId) {
return (getEnabledColumns())[columnId];
}
/**
* Sets the given column either enabled or disabled.
* @param {string} columnId The ID of the collumn to be set.
* @param {boolean} newChecked True, to set the column enable. False otherwise.
*/
function setColumnEnabled(columnId, newChecked) {
commands.setUpdateColumn(columnId, newChecked);
cachedEnabledColumns[columnId] = newChecked;
var json = JSON.stringify(cachedEnabledColumns);
window.localStorage.setItem(ENABLED_COLUMNS_KEY, json);
}
// Enable the taskmanager model before the loading of scripts.
(function() {
for (var i = 0; i < DEFAULT_COLUMNS.length; i++) {
var columnId = DEFAULT_COLUMNS[i][0];
if (isColumnEnabled(columnId))
commands.setUpdateColumn(columnId, true);
}
commands.enableTaskManager();
commands.setUpdateColumn('canInspect', true);
commands.setUpdateColumn('canActivate', true);
})();
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
html {
overflow: hidden;
}
/* Outer frame of the dialog. */
body {
-webkit-box-orient: vertical;
-webkit-user-select: none;
display: -webkit-box;
font-family: segoe ui, arial, helvetica, sans-serif;
font-size: 12px;
height: 100%;
min-height: 150px;
position: absolute;
width: 100%;
}
/* Container for the detail list views. */
.dialog-body {
-webkit-box-flex: 1;
border: 1px #aaa solid;
border-radius: 3px;
display: -webkit-box;
margin: 12px 12px 6px;
}
/* Column text containers. */
.list-container {
-webkit-box-flex: 1;
display: -webkit-box;
}
/* Table splitter element */
.table-header-splitter {
-webkit-border-start: 1px #aaa solid;
background-color: inherit;
height: 20px;
margin-top: 4px;
}
/* Container for a table header. */
.table-header {
-webkit-box-sizing: border-box;
background-image: -webkit-linear-gradient(top, #f9f9f9, #e8e8e8);
border-bottom: 1px #aaa solid;
height: 28px;
}
/* Text label in a table header. */
.table-header-label {
cursor: default;
margin-top: 6px;
}
/* Task list in table. */
.list {
-webkit-box-flex: 1;
}
/* Title Column text containers. */
.detail-title {
display: -webkit-box;
height: 20px;
}
/* Bullets on the left of row. */
.table-row > .table-row-cell:first-child::before {
-webkit-border-radius: 3px;
background: #ccc;
content: '';
display: block;
margin: 7px 4px 7px 7px;
width: 6px;
}
/* Cells in table. */
.table-row-cell {
-webkit-box-orient: horizontal;
display: -webkit-box;
}
/* Containers of titles of tasks on the process. */
.detail-container-title {
-webkit-box-flex: 1;
-webkit-box-orient: vertical;
display: -webkit-box;
margin-left: 3px;
}
.detail-title-image {
height: 16px;
padding: 2px;
width: 16px;
}
.detail-title-text {
height: 20px;
padding-left: 1px;
}
/* Entire Table (including column header). */
.detail-table {
-webkit-box-flex: 1;
-webkit-box-orient: vertical;
border: 0;
display: -webkit-box;
}
/* cr.ui.Table has a black focus border by default, which we don't want. */
.detail-table:focus {
border: 0;
}
/* Container for footer area. */
.dialog-footer {
display: -webkit-box;
margin: 6px 12px 12px;
}
/* Container for the ok/cancel buttons. */
.footer-left-container {
-webkit-box-align: center;
-webkit-box-flex: 1;
display: -webkit-box;
text-align: left;
}
#about-memory-link {
color: rgb(17, 85, 204);
padding-left: 2px;
}
/* Container for the ok/cancel buttons. */
.footer-right-container {
-webkit-box-flex: 1;
text-align: right;
}
button {
margin: 2px 0 2px 8px;
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/task_manager/task_manager_dialog.h"
#include <algorithm>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/singleton.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "grit/google_chrome_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/size.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
#if defined(OS_CHROMEOS)
#include "ui/views/widget/widget.h"
#endif
namespace {
// The minimum size of task manager window in px.
const int kMinimumTaskManagerWidth = 640;
const int kMinimumTaskManagerHeight = 480;
} // namespace
using content::BrowserThread;
using content::WebContents;
using content::WebUIMessageHandler;
using ui::WebDialogDelegate;
class TaskManagerDialogImpl : public WebDialogDelegate {
public:
TaskManagerDialogImpl();
static void Show(bool is_background_page_mode);
static TaskManagerDialogImpl* GetInstance();
protected:
friend struct DefaultSingletonTraits<TaskManagerDialogImpl>;
virtual ~TaskManagerDialogImpl();
void OnCloseDialog();
// Overridden from WebDialogDelegate:
virtual ui::ModalType GetDialogModalType() const OVERRIDE {
return ui::MODAL_TYPE_NONE;
}
virtual base::string16 GetDialogTitle() const OVERRIDE {
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_TITLE);
}
virtual std::string GetDialogName() const OVERRIDE {
return prefs::kTaskManagerWindowPlacement;
}
virtual GURL GetDialogContentURL() const OVERRIDE {
std::string url_string(chrome::kChromeUITaskManagerURL);
url_string += "?";
if (browser_defaults::kShowCancelButtonInTaskManager)
url_string += "showclose=1&";
if (is_background_page_mode_)
url_string += "background=1";
return GURL(url_string);
}
virtual void GetWebUIMessageHandlers(
std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE {
}
virtual void GetDialogSize(gfx::Size* size) const OVERRIDE {
#if !defined(TOOLKIT_VIEWS)
// If dialog's bounds are previously saved, use them.
if (g_browser_process->local_state()) {
const base::DictionaryValue* placement_pref =
g_browser_process->local_state()->GetDictionary(
prefs::kTaskManagerWindowPlacement);
int width, height;
if (placement_pref &&
placement_pref->GetInteger("width", &width) &&
placement_pref->GetInteger("height", &height)) {
size->SetSize(std::max(1, width), std::max(1, height));
return;
}
}
// Otherwise set default size.
size->SetSize(kMinimumTaskManagerWidth, kMinimumTaskManagerHeight);
#endif
}
virtual void GetMinimumDialogSize(gfx::Size* size) const OVERRIDE {
size->SetSize(kMinimumTaskManagerWidth, kMinimumTaskManagerHeight);
}
virtual std::string GetDialogArgs() const OVERRIDE {
return std::string();
}
virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE {
OnCloseDialog();
}
virtual void OnCloseContents(WebContents* source, bool* out_close_dialog)
OVERRIDE {
*out_close_dialog = true;
}
virtual bool ShouldShowDialogTitle() const OVERRIDE {
return true;
}
virtual bool HandleContextMenu(
const content::ContextMenuParams& params) OVERRIDE {
return true;
}
#if !defined(TOOLKIT_VIEWS)
virtual void StoreDialogSize(const gfx::Size& dialog_size) OVERRIDE {
// Store the dialog's bounds so that it can be restored with the same bounds
// the next time it's opened.
if (g_browser_process->local_state()) {
DictionaryPrefUpdate update(g_browser_process->local_state(),
prefs::kTaskManagerWindowPlacement);
base::DictionaryValue* placement_pref = update.Get();
placement_pref->SetInteger("width", dialog_size.width());
placement_pref->SetInteger("height", dialog_size.height());
}
}
#endif
private:
void ShowDialog(bool is_background_page_mode);
void OpenWebDialog();
int show_count_;
gfx::NativeWindow window_;
bool is_background_page_mode_;
DISALLOW_COPY_AND_ASSIGN(TaskManagerDialogImpl);
};
// ****************************************************
// static
TaskManagerDialogImpl* TaskManagerDialogImpl::GetInstance() {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
return Singleton<TaskManagerDialogImpl>::get();
}
TaskManagerDialogImpl::TaskManagerDialogImpl()
: show_count_(0),
window_(NULL),
is_background_page_mode_(false) {
}
TaskManagerDialogImpl::~TaskManagerDialogImpl() {
}
// static
void TaskManagerDialogImpl::Show(bool is_background_page_mode) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
TaskManagerDialogImpl* dialog = TaskManagerDialogImpl::GetInstance();
dialog->ShowDialog(is_background_page_mode);
}
void TaskManagerDialogImpl::ShowDialog(bool is_background_page_mode) {
if (show_count_ > 0) {
#if defined(OS_CHROMEOS)
// Closes current TaskManager and Opens new one.
views::Widget::GetWidgetForNativeWindow(window_)->Close();
#else
// TODO(yoshiki): Supports the other platforms.
platform_util::ActivateWindow(window_);
return;
#endif
}
is_background_page_mode_ = is_background_page_mode;
OpenWebDialog();
++show_count_;
}
void TaskManagerDialogImpl::OnCloseDialog() {
if (show_count_ > 0)
--show_count_;
}
void TaskManagerDialogImpl::OpenWebDialog() {
window_ = chrome::ShowWebDialog(NULL,
ProfileManager::GetLastUsedProfile(),
this);
}
// static
void TaskManagerDialog::Show() {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&TaskManagerDialogImpl::Show, false));
}
// static
void TaskManagerDialog::ShowBackgroundPages() {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&TaskManagerDialogImpl::Show, true));
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_DIALOG_H_
#define CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_DIALOG_H_
class TaskManagerDialog {
public:
static void Show();
static void ShowBackgroundPages();
};
#endif // CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_DIALOG_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/task_manager/task_manager_handler.h"
#include <algorithm>
#include <functional>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "chrome/browser/ui/host_desktop.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/gfx/image/image_skia.h"
#include "webkit/common/webpreferences.h"
namespace {
struct ColumnType {
const char* column_id;
// Whether the column has the real value separately or not, instead of the
// formatted value to display.
const bool has_real_value;
// Whether the column has single datum or multiple data in each group.
const bool has_multiple_data;
};
const ColumnType kColumnsList[] = {
{"type", false, false},
{"processId", true, false},
{"cpuUsage", true, false},
{"physicalMemory", true, false},
{"sharedMemory", true, false},
{"privateMemory", true, false},
{"webCoreImageCacheSize", true, false},
{"webCoreImageCacheSize", true, false},
{"webCoreScriptsCacheSize", true, false},
{"webCoreCSSCacheSize", true, false},
{"sqliteMemoryUsed", true, false},
{"v8MemoryAllocatedSize", true, false},
{"icon", false, true},
{"title", false, true},
{"profileName", false, true},
{"networkUsage", true, true},
{"fps", true, true},
{"videoMemory", true, false},
{"goatsTeleported", true, true},
{"canInspect", false, true},
{"canActivate", false, true}
};
} // namespace
TaskManagerHandler::TaskManagerHandler(TaskManager* tm)
: task_manager_(tm),
model_(tm->model()),
is_enabled_(false) {
}
TaskManagerHandler::~TaskManagerHandler() {
DisableTaskManager(NULL);
}
// TaskManagerHandler, public: -----------------------------------------------
void TaskManagerHandler::OnModelChanged() {
OnGroupChanged(0, model_->GroupCount());
}
void TaskManagerHandler::OnItemsChanged(const int start, const int length) {
OnGroupChanged(0, model_->GroupCount());
}
void TaskManagerHandler::OnItemsAdded(const int start, const int length) {
}
void TaskManagerHandler::OnItemsRemoved(const int start, const int length) {
}
void TaskManagerHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback("killProcesses",
base::Bind(&TaskManagerHandler::HandleKillProcesses,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("inspect",
base::Bind(&TaskManagerHandler::HandleInspect,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("activatePage",
base::Bind(&TaskManagerHandler::HandleActivatePage,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("openAboutMemory",
base::Bind(&TaskManagerHandler::OpenAboutMemory,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("enableTaskManager",
base::Bind(&TaskManagerHandler::EnableTaskManager,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("disableTaskManager",
base::Bind(&TaskManagerHandler::DisableTaskManager,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("setUpdateColumn",
base::Bind(&TaskManagerHandler::HandleSetUpdateColumn,
base::Unretained(this)));
}
static int parseIndex(const base::Value* value) {
int index = -1;
base::string16 base::string16_index;
double double_index;
if (value->GetAsString(&string16_index)) {
bool converted = base::StringToInt(base::string16_index, &index);
DCHECK(converted);
} else if (value->GetAsDouble(&double_index)) {
index = static_cast<int>(double_index);
} else {
value->GetAsInteger(&index);
}
return index;
}
void TaskManagerHandler::HandleKillProcesses(
const base::ListValue* unique_ids) {
for (base::ListValue::const_iterator i = unique_ids->begin();
i != unique_ids->end(); ++i) {
int unique_id = parseIndex(*i);
int resource_index = model_->GetResourceIndexByUniqueId(unique_id);
if (resource_index == -1)
continue;
task_manager_->KillProcess(resource_index);
}
}
void TaskManagerHandler::HandleActivatePage(const base::ListValue* unique_ids) {
for (base::ListValue::const_iterator i = unique_ids->begin();
i != unique_ids->end(); ++i) {
int unique_id = parseIndex(*i);
int resource_index = model_->GetResourceIndexByUniqueId(unique_id);
if (resource_index == -1)
continue;
task_manager_->ActivateProcess(resource_index);
break;
}
}
void TaskManagerHandler::HandleInspect(const base::ListValue* unique_ids) {
for (base::ListValue::const_iterator i = unique_ids->begin();
i != unique_ids->end(); ++i) {
int unique_id = parseIndex(*i);
int resource_index = model_->GetResourceIndexByUniqueId(unique_id);
if (resource_index == -1)
continue;
if (model_->CanInspect(resource_index))
model_->Inspect(resource_index);
break;
}
}
void TaskManagerHandler::DisableTaskManager(const base::ListValue* indexes) {
if (!is_enabled_)
return;
is_enabled_ = false;
model_->StopUpdating();
model_->RemoveObserver(this);
}
void TaskManagerHandler::EnableTaskManager(const base::ListValue* indexes) {
if (is_enabled_)
return;
is_enabled_ = true;
OnGroupChanged(0, model_->GroupCount());
model_->AddObserver(this);
model_->StartUpdating();
}
void TaskManagerHandler::OpenAboutMemory(const base::ListValue* indexes) {
content::RenderViewHost* rvh =
web_ui()->GetWebContents()->GetRenderViewHost();
if (rvh) {
WebPreferences webkit_prefs = rvh->GetWebkitPreferences();
webkit_prefs.allow_scripts_to_close_windows = true;
rvh->UpdateWebkitPreferences(webkit_prefs);
} else {
DCHECK(false);
}
task_manager_->OpenAboutMemory(chrome::GetActiveDesktop());
}
void TaskManagerHandler::HandleSetUpdateColumn(const base::ListValue* args) {
DCHECK_EQ(2U, args->GetSize());
bool ret = true;
std::string column_id;
ret &= args->GetString(0, &column_id);
bool is_enabled;
ret &= args->GetBoolean(1, &is_enabled);
DCHECK(ret);
if (is_enabled)
enabled_columns_.insert(column_id);
else
enabled_columns_.erase(column_id);
}
// TaskManagerHandler, private: -----------------------------------------------
bool TaskManagerHandler::is_alive() {
return web_ui()->GetWebContents()->GetRenderViewHost() != NULL;
}
void TaskManagerHandler::OnGroupChanged(const int group_start,
const int group_length) {
base::FundamentalValue start_value(group_start);
base::FundamentalValue length_value(group_length);
base::ListValue tasks_value;
for (int i = 0; i < group_length; ++i) {
tasks_value.Append(CreateTaskGroupValue(group_start + i));
}
if (is_enabled_ && is_alive()) {
web_ui()->CallJavascriptFunction("taskChanged",
start_value, length_value, tasks_value);
}
}
void TaskManagerHandler::OnGroupAdded(const int group_start,
const int group_length) {
}
void TaskManagerHandler::OnGroupRemoved(const int group_start,
const int group_length) {
}
void TaskManagerHandler::OnReadyPeriodicalUpdate() {
}
base::DictionaryValue* TaskManagerHandler::CreateTaskGroupValue(
int group_index) {
base::DictionaryValue* val = new base::DictionaryValue();
if (group_index >= model_->GroupCount())
return val;
int index = model_->GetResourceIndexForGroup(group_index, 0);
int length = model_->GetGroupRangeForResource(index).second;
// Forces to set following column regardless of |enable_columns|.
val->SetInteger("index", index);
CreateGroupColumnList("processId", index, 1, val);
CreateGroupColumnList("type", index, length, val);
CreateGroupColumnList("uniqueId", index, length, val);
for (size_t i = 0; i < arraysize(kColumnsList); ++i) {
const std::string column_id = kColumnsList[i].column_id;
if (enabled_columns_.find(column_id) == enabled_columns_.end())
continue;
int column_length = kColumnsList[i].has_multiple_data ? length : 1;
CreateGroupColumnList(column_id, index, column_length, val);
if (kColumnsList[i].has_real_value)
CreateGroupColumnList(column_id + "Value", index, column_length, val);
}
return val;
}
void TaskManagerHandler::CreateGroupColumnList(const std::string& column_name,
const int index,
const int length,
base::DictionaryValue* val) {
base::ListValue* list = new base::ListValue();
for (int i = index; i < (index + length); ++i) {
list->Append(CreateColumnValue(column_name, i));
}
val->Set(column_name, list);
}
base::Value* TaskManagerHandler::CreateColumnValue(
const std::string& column_name,
const int i) {
if (column_name == "uniqueId")
return base::Value::CreateIntegerValue(model_->GetResourceUniqueId(i));
if (column_name == "type") {
return base::Value::CreateStringValue(
TaskManager::Resource::GetResourceTypeAsString(
model_->GetResourceType(i)));
}
if (column_name == "processId")
return base::Value::CreateStringValue(model_->GetResourceProcessId(i));
if (column_name == "processIdValue")
return base::Value::CreateIntegerValue(model_->GetProcessId(i));
if (column_name == "cpuUsage")
return base::Value::CreateStringValue(model_->GetResourceCPUUsage(i));
if (column_name == "cpuUsageValue")
return base::Value::CreateDoubleValue(model_->GetCPUUsage(i));
if (column_name == "privateMemory")
return base::Value::CreateStringValue(model_->GetResourcePrivateMemory(i));
if (column_name == "privateMemoryValue") {
size_t private_memory;
model_->GetPrivateMemory(i, &private_memory);
return base::Value::CreateDoubleValue(private_memory);
}
if (column_name == "sharedMemory")
return base::Value::CreateStringValue(model_->GetResourceSharedMemory(i));
if (column_name == "sharedMemoryValue") {
size_t shared_memory;
model_->GetSharedMemory(i, &shared_memory);
return base::Value::CreateDoubleValue(shared_memory);
}
if (column_name == "physicalMemory")
return base::Value::CreateStringValue(model_->GetResourcePhysicalMemory(i));
if (column_name == "physicalMemoryValue") {
size_t physical_memory;
model_->GetPhysicalMemory(i, &physical_memory);
return base::Value::CreateDoubleValue(physical_memory);
}
if (column_name == "icon") {
ui::ScaleFactor icon_scale_factor = web_ui()->GetDeviceScaleFactor();
const gfx::ImageSkia& image = model_->GetResourceIcon(i);
const gfx::ImageSkiaRep image_rep =
image.GetRepresentation(icon_scale_factor);
return base::Value::CreateStringValue(
webui::GetBitmapDataUrl(image_rep.sk_bitmap()));
}
if (column_name == "title")
return base::Value::CreateStringValue(model_->GetResourceTitle(i));
if (column_name == "profileName")
return base::Value::CreateStringValue(model_->GetResourceProfileName(i));
if (column_name == "networkUsage")
return base::Value::CreateStringValue(model_->GetResourceNetworkUsage(i));
if (column_name == "networkUsageValue")
return base::Value::CreateDoubleValue(model_->GetNetworkUsage(i));
if (column_name == "webCoreImageCacheSize") {
return base::Value::CreateStringValue(
model_->GetResourceWebCoreImageCacheSize(i));
}
if (column_name == "webCoreImageCacheSizeValue") {
blink::WebCache::ResourceTypeStats resource_stats;
model_->GetWebCoreCacheStats(i, &resource_stats);
return base::Value::CreateDoubleValue(resource_stats.images.size);
}
if (column_name == "webCoreScriptsCacheSize") {
return base::Value::CreateStringValue(
model_->GetResourceWebCoreScriptsCacheSize(i));
}
if (column_name == "webCoreScriptsCacheSizeValue") {
blink::WebCache::ResourceTypeStats resource_stats;
model_->GetWebCoreCacheStats(i, &resource_stats);
return base::Value::CreateDoubleValue(resource_stats.scripts.size);
}
if (column_name == "webCoreCSSCacheSize") {
return base::Value::CreateStringValue(
model_->GetResourceWebCoreCSSCacheSize(i));
}
if (column_name == "webCoreCSSCacheSizeValue") {
blink::WebCache::ResourceTypeStats resource_stats;
model_->GetWebCoreCacheStats(i, &resource_stats);
return base::Value::CreateDoubleValue(resource_stats.cssStyleSheets.size);
}
if (column_name == "fps")
return base::Value::CreateStringValue(model_->GetResourceFPS(i));
if (column_name == "fpsValue") {
float fps;
model_->GetFPS(i, &fps);
return base::Value::CreateDoubleValue(fps);
}
if (column_name == "videoMemory")
return base::Value::CreateStringValue(model_->GetResourceVideoMemory(i));
if (column_name == "videoMemoryValue") {
size_t video_memory;
bool has_duplicates;
double value;
if (model_->GetVideoMemory(i, &video_memory, &has_duplicates))
value = static_cast<double>(video_memory);
else
value = 0;
return base::Value::CreateDoubleValue(value);
}
if (column_name == "sqliteMemoryUsed") {
return base::Value::CreateStringValue(
model_->GetResourceSqliteMemoryUsed(i));
}
if (column_name == "sqliteMemoryUsedValue") {
size_t sqlite_memory;
model_->GetSqliteMemoryUsedBytes(i, &sqlite_memory);
return base::Value::CreateDoubleValue(sqlite_memory);
}
if (column_name == "goatsTeleported") {
return base::Value::CreateStringValue(
model_->GetResourceGoatsTeleported(i));
}
if (column_name == "goatsTeleportedValue")
return base::Value::CreateIntegerValue(model_->GetGoatsTeleported(i));
if (column_name == "v8MemoryAllocatedSize") {
return base::Value::CreateStringValue(
model_->GetResourceV8MemoryAllocatedSize(i));
}
if (column_name == "v8MemoryAllocatedSizeValue") {
size_t v8_memory;
model_->GetV8Memory(i, &v8_memory);
return base::Value::CreateDoubleValue(v8_memory);
}
if (column_name == "canInspect")
return base::Value::CreateBooleanValue(model_->CanInspect(i));
if (column_name == "canActivate")
return base::Value::CreateBooleanValue(model_->CanActivate(i));
NOTREACHED();
return NULL;
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_HANDLER_H_
#include <set>
#include <string>
#include <vector>
#include "content/public/browser/web_ui_message_handler.h"
#include "chrome/browser/task_manager/task_manager.h"
namespace base {
class ListValue;
class Value;
}
class TaskManagerHandler : public content::WebUIMessageHandler,
public TaskManagerModelObserver {
public:
explicit TaskManagerHandler(TaskManager* tm);
virtual ~TaskManagerHandler();
// TaskManagerModelObserver implementation.
// Invoked when the model has been completely changed.
virtual void OnModelChanged() OVERRIDE;
// Invoked when a range of items has changed.
virtual void OnItemsChanged(int start, int length) OVERRIDE;
// Invoked when new items are added.
virtual void OnItemsAdded(int start, int length) OVERRIDE;
// Invoked when a range of items has been removed.
virtual void OnItemsRemoved(int start, int length) OVERRIDE;
// Invoked when the initialization of the model has been finished and
// periodic updates is started.
virtual void OnReadyPeriodicalUpdate() OVERRIDE;
// WebUIMessageHandler implementation.
virtual void RegisterMessages() OVERRIDE;
// Callback for the "killProcesses" message.
void HandleKillProcesses(const base::ListValue* indexes);
// Callback for the "activatePage" message.
void HandleActivatePage(const base::ListValue* resource_index);
// Callback for the "inspect" message.
void HandleInspect(const base::ListValue* resource_index);
void EnableTaskManager(const base::ListValue* indexes);
void DisableTaskManager(const base::ListValue* indexes);
void OpenAboutMemory(const base::ListValue* indexes);
// Callback for the "setUpdateColumn" message.
void HandleSetUpdateColumn(const base::ListValue* args);
private:
bool is_alive();
// Models
TaskManager* task_manager_;
TaskManagerModel* model_;
bool is_enabled_;
// Set to store the enabled columns.
std::set<std::string> enabled_columns_;
// Invoked when group(s) are added/changed/removed.
// These method are called from OnItemAdded/-Changed/-Removed internally.
void OnGroupAdded(int start, int length);
void OnGroupChanged(int start, int length);
void OnGroupRemoved(int start, int length);
// Creates or updates information for a single task group. A task group is a
// group of tasks associated with a single process ID. |group_index| is the
// integer index of the target process within the data model.
base::DictionaryValue* CreateTaskGroupValue(int group_index);
// Creates a list of values to display within a single column of the task
// manager for a single task group. |columnn_name| is the name of the column.
// |index| is the index of the resources associated with a process group.
// |length| is the number of values associated with the group, and is either
// 1 if all tasks within the group share a common value or equal to the
// number of tasks within the group.
void CreateGroupColumnList(const std::string& column_name,
const int index,
const int length,
base::DictionaryValue* val);
// Retrieves the value of a property for a single task. |column_name| is the
// name of the property, which is associated with a column within the task
// manager or "about memory" page. |i| is the index of the task. Tasks are
// grouped by process ID, and the index of the task is the sum of the group
// offset and the index of the task within the group.
base::Value* CreateColumnValue(const std::string& column_name,
const int i);
DISALLOW_COPY_AND_ASSIGN(TaskManagerHandler);
};
#endif // CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_HANDLER_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/task_manager/task_manager_ui.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "chrome/browser/ui/webui/task_manager/task_manager_handler.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
#include "grit/chromium_strings.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
using content::WebContents;
namespace {
content::WebUIDataSource* CreateTaskManagerUIHTMLSource() {
content::WebUIDataSource* source =
content::WebUIDataSource::Create(chrome::kChromeUITaskManagerHost);
source->SetUseJsonJSFormatV2();
source->AddLocalizedString("closeWindow", IDS_CLOSE);
source->AddLocalizedString("title", IDS_TASK_MANAGER_TITLE);
source->AddLocalizedString("aboutMemoryLink",
IDS_TASK_MANAGER_ABOUT_MEMORY_LINK);
source->AddLocalizedString("killButton", IDS_TASK_MANAGER_KILL);
source->AddLocalizedString("processIDColumn",
IDS_TASK_MANAGER_PROCESS_ID_COLUMN);
source->AddLocalizedString("taskColumn", IDS_TASK_MANAGER_TASK_COLUMN);
source->AddLocalizedString("profileNameColumn",
IDS_TASK_MANAGER_PROFILE_NAME_COLUMN);
source->AddLocalizedString("netColumn", IDS_TASK_MANAGER_NET_COLUMN);
source->AddLocalizedString("cpuColumn", IDS_TASK_MANAGER_CPU_COLUMN);
source->AddLocalizedString("physicalMemColumn",
IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN);
source->AddLocalizedString("sharedMemColumn",
IDS_TASK_MANAGER_SHARED_MEM_COLUMN);
source->AddLocalizedString("privateMemColumn",
IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN);
source->AddLocalizedString("goatsTeleportedColumn",
IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN);
source->AddLocalizedString("webcoreImageCacheColumn",
IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN);
source->AddLocalizedString("webcoreScriptsCacheColumn",
IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN);
source->AddLocalizedString("webcoreCSSCacheColumn",
IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN);
source->AddLocalizedString("videoMemoryColumn",
IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN);
source->AddLocalizedString("fpsColumn", IDS_TASK_MANAGER_FPS_COLUMN);
source->AddLocalizedString("sqliteMemoryUsedColumn",
IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN);
source->AddLocalizedString(
"javascriptMemoryAllocatedColumn",
IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN);
source->AddLocalizedString("inspect", IDS_TASK_MANAGER_INSPECT);
source->AddLocalizedString("activate", IDS_TASK_MANAGER_ACTIVATE);
source->SetJsonPath("strings.js");
source->AddResourcePath("main.js", IDR_TASK_MANAGER_JS);
source->AddResourcePath("commands.js", IDR_TASK_MANAGER_COMMANDS_JS);
source->AddResourcePath("defines.js", IDR_TASK_MANAGER_DEFINES_JS);
source->AddResourcePath("includes.js", IDR_TASK_MANAGER_INCLUDES_JS);
source->AddResourcePath("preload.js", IDR_TASK_MANAGER_PRELOAD_JS);
source->AddResourcePath("measure_time.js", IDR_TASK_MANAGER_MEASURE_TIME_JS);
source->AddResourcePath("measure_time_end.js",
IDR_TASK_MANAGER_MEASURE_TIME_END_JS);
source->SetDefaultResource(IDR_TASK_MANAGER_HTML);
return source;
}
} // namespace
///////////////////////////////////////////////////////////////////////////////
//
// TaskManagerUI
//
///////////////////////////////////////////////////////////////////////////////
TaskManagerUI::TaskManagerUI(content::WebUI* web_ui) : WebUIController(web_ui) {
web_ui->AddMessageHandler(new TaskManagerHandler(TaskManager::GetInstance()));
// Set up the chrome://taskmanager/ source.
content::WebUIDataSource* html_source = CreateTaskManagerUIHTMLSource();
Profile* profile = Profile::FromWebUI(web_ui);
content::WebUIDataSource::Add(profile, html_source);
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_UI_H_
#define CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_UI_H_
#include "content/public/browser/web_ui_controller.h"
class TaskManagerUI : public content::WebUIController {
public:
explicit TaskManagerUI(content::WebUI* web_ui);
private:
DISALLOW_COPY_AND_ASSIGN(TaskManagerUI);
};
#endif // CHROME_BROWSER_UI_WEBUI_TASK_MANAGER_TASK_MANAGER_UI_H_
...@@ -2588,12 +2588,6 @@ ...@@ -2588,12 +2588,6 @@
'browser/ui/webui/sync_setup_handler.h', 'browser/ui/webui/sync_setup_handler.h',
'browser/ui/webui/system_info_ui.cc', 'browser/ui/webui/system_info_ui.cc',
'browser/ui/webui/system_info_ui.h', 'browser/ui/webui/system_info_ui.h',
'browser/ui/webui/task_manager/task_manager_dialog.cc',
'browser/ui/webui/task_manager/task_manager_dialog.h',
'browser/ui/webui/task_manager/task_manager_handler.cc',
'browser/ui/webui/task_manager/task_manager_handler.h',
'browser/ui/webui/task_manager/task_manager_ui.cc',
'browser/ui/webui/task_manager/task_manager_ui.h',
'browser/ui/webui/theme_handler.cc', 'browser/ui/webui/theme_handler.cc',
'browser/ui/webui/theme_handler.h', 'browser/ui/webui/theme_handler.h',
'browser/ui/webui/theme_source.cc', 'browser/ui/webui/theme_source.cc',
...@@ -2715,7 +2709,6 @@ ...@@ -2715,7 +2709,6 @@
}], }],
['enable_task_manager==0', { ['enable_task_manager==0', {
'sources/': [ 'sources/': [
['exclude', '^browser/ui/webui/task_manager/'],
['exclude', '^browser/ui/views/task_manager_view.cc'], ['exclude', '^browser/ui/views/task_manager_view.cc'],
['exclude', '^browser/ui/cocoa/task_manager_mac.h'], ['exclude', '^browser/ui/cocoa/task_manager_mac.h'],
['exclude', '^browser/ui/cocoa/task_manager_mac.mm'], ['exclude', '^browser/ui/cocoa/task_manager_mac.mm'],
...@@ -2906,7 +2899,6 @@ ...@@ -2906,7 +2899,6 @@
['exclude', '^browser/ui/views/user_data_dir_dialog_view.cc'], ['exclude', '^browser/ui/views/user_data_dir_dialog_view.cc'],
['exclude', '^browser/ui/views/tab_contents/web_drag_bookmark_handler_win.cc'], ['exclude', '^browser/ui/views/tab_contents/web_drag_bookmark_handler_win.cc'],
['exclude', '^browser/ui/views/tab_contents/web_drag_bookmark_handler_win.h'], ['exclude', '^browser/ui/views/tab_contents/web_drag_bookmark_handler_win.h'],
['exclude', '^browser/ui/webui/task_manager/'],
['exclude', '^browser/ui/window_sizer/window_sizer_win.cc'], ['exclude', '^browser/ui/window_sizer/window_sizer_win.cc'],
# TODO: (stevenjb/beng): Find a home for these. # TODO: (stevenjb/beng): Find a home for these.
['include', '^browser/ui/views/simple_message_box_views.cc'], ['include', '^browser/ui/views/simple_message_box_views.cc'],
...@@ -2957,7 +2949,6 @@ ...@@ -2957,7 +2949,6 @@
['exclude', '^browser/ui/webui/gesture_config_ui.h'], ['exclude', '^browser/ui/webui/gesture_config_ui.h'],
['exclude', '^browser/ui/webui/salsa_ui.cc'], ['exclude', '^browser/ui/webui/salsa_ui.cc'],
['exclude', '^browser/ui/webui/salsa_ui.h'], ['exclude', '^browser/ui/webui/salsa_ui.h'],
['exclude', '^browser/ui/webui/task_manager/'],
], ],
}], }],
['ui_compositor_image_transport==1', { ['ui_compositor_image_transport==1', {
......
...@@ -2179,7 +2179,6 @@ ...@@ -2179,7 +2179,6 @@
['enable_task_manager==0', { ['enable_task_manager==0', {
'sources/': [ 'sources/': [
['exclude', '^browser/task_manager/'], ['exclude', '^browser/task_manager/'],
['exclude', '^browser/ui/webui/task_manager/'],
], ],
}], }],
['file_manager_extension==0', { ['file_manager_extension==0', {
......
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