summaryrefslogtreecommitdiffstats
path: root/tools/memory_inspector
diff options
context:
space:
mode:
authorprimiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-13 15:18:16 +0000
committerprimiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-13 15:18:16 +0000
commitc2d2ef92677c79d67d637e5bb613f059c5aca18b (patch)
treeb9dc237638718f13d8798f8e31f922583fc7ddbb /tools/memory_inspector
parent990636841d4924f06103e0fb1d102791efe969d6 (diff)
downloadchromium_src-c2d2ef92677c79d67d637e5bb613f059c5aca18b.zip
chromium_src-c2d2ef92677c79d67d637e5bb613f059c5aca18b.tar.gz
chromium_src-c2d2ef92677c79d67d637e5bb613f059c5aca18b.tar.bz2
Add settings UI to the memory_inspector
This CL adds the HTML UI for loading/storing backend and device-specific settings (plus the required server-side wiring). BUG=340294 NOTRY=true Review URL: https://codereview.chromium.org/194983005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256835 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/memory_inspector')
-rw-r--r--tools/memory_inspector/memory_inspector/core/backends.py10
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_content/index.html2
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_content/js/devices.js12
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_content/js/rootUi.js9
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_content/js/settings.js90
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_content/settings.css25
-rw-r--r--tools/memory_inspector/memory_inspector/frontends/www_server.py53
7 files changed, 194 insertions, 7 deletions
diff --git a/tools/memory_inspector/memory_inspector/core/backends.py b/tools/memory_inspector/memory_inspector/core/backends.py
index aa4c6c6..9eeb521 100644
--- a/tools/memory_inspector/memory_inspector/core/backends.py
+++ b/tools/memory_inspector/memory_inspector/core/backends.py
@@ -189,12 +189,12 @@ class Settings(object):
expected_keys: A dict. (key-name -> description) of expected settings
"""
self.expected_keys = expected_keys or {}
- self._settings = dict((k, '') for k in self.expected_keys.iterkeys())
+ self.values = dict((k, '') for k in self.expected_keys.iterkeys())
def __getitem__(self, key):
- assert(key in self.expected_keys)
- return self._settings.get(key)
+ assert(key in self.expected_keys), 'Unexpected setting: ' + key
+ return self.values.get(key)
def __setitem__(self, key, value):
- assert(key in self.expected_keys)
- self._settings[key] = value
+ assert(key in self.expected_keys), 'Unexpected setting: ' + key
+ self.values[key] = value
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_content/index.html b/tools/memory_inspector/memory_inspector/frontends/www_content/index.html
index eaf8a3f..22d130c 100644
--- a/tools/memory_inspector/memory_inspector/frontends/www_content/index.html
+++ b/tools/memory_inspector/memory_inspector/frontends/www_content/index.html
@@ -11,6 +11,7 @@
<link href='//fonts.googleapis.com/css?family=Coda' rel='stylesheet' type='text/css'>
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/flick/jquery-ui.css" rel="stylesheet">
<link href="/rootUi.css" rel="stylesheet" type="text/css">
+ <link href="/settings.css" rel="stylesheet" type="text/css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="//www.google.com/jsapi"></script>
@@ -21,6 +22,7 @@
<script src="/js/devices.js"></script>
<script src="/js/rootUi.js"></script>
<script src="/js/processes.js"></script>
+ <script src="/js/settings.js"></script>
<script src="/js/timers.js"></script>
<script src="/js/webservice.js"></script>
</head>
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_content/js/devices.js b/tools/memory_inspector/memory_inspector/frontends/www_content/js/devices.js
index b4c4ce2..ba6e755 100644
--- a/tools/memory_inspector/memory_inspector/frontends/www_content/js/devices.js
+++ b/tools/memory_inspector/memory_inspector/frontends/www_content/js/devices.js
@@ -38,10 +38,13 @@ this.refresh = function() {
this.onBackendsAjaxResponse_ = function(data) {
if (!data || !data.length)
{
- rootUi.ShowDialog('No backends detected! Memory Inspector looks terribly' +
+ rootUi.showDialog('No backends detected! Memory Inspector looks terribly' +
' broken. Please file a bug');
}
this.backends_ = data;
+
+ // Reload settings now that both devices and backends have been enumerated.
+ settings.reload();
};
this.onDevicesAjaxResponse_ = function(data) {
@@ -56,7 +59,12 @@ this.onDevicesAjaxResponse_ = function(data) {
this.devices_[deviceUri] = device;
}, this);
- this.onDeviceSelectionChange_(); // start monitoring the first device.
+ if (data.length > 0) {
+ this.onDeviceSelectionChange_(); // Start monitoring the first device.
+ } else {
+ rootUi.showDialog('No devices could be detected. Check the settings tab ' +
+ 'to ensure that the adb path is properly configured.');
+ }
};
this.onDeviceSelectionChange_ = function() {
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_content/js/rootUi.js b/tools/memory_inspector/memory_inspector/frontends/www_content/js/rootUi.js
index 94d4d30..a9e85de 100644
--- a/tools/memory_inspector/memory_inspector/frontends/www_content/js/rootUi.js
+++ b/tools/memory_inspector/memory_inspector/frontends/www_content/js/rootUi.js
@@ -36,6 +36,15 @@ this.showTab = function(tabId) {
$('#tabs').tabs('option', 'active', index - 1);
};
+this.showDialog = function(message) {
+ var dialog = $("#message_dialog");
+ if (dialog.length == 0) {
+ dialog = $('<div id="message_dialog"/>');
+ $('body').append(dialog);
+ }
+ $("#message_dialog").text(message).dialog({ modal: true });
+};
+
$(document).ready(this.onDomReady_.bind(this));
})(); \ No newline at end of file
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_content/js/settings.js b/tools/memory_inspector/memory_inspector/frontends/www_content/js/settings.js
new file mode 100644
index 0000000..30d71cf
--- /dev/null
+++ b/tools/memory_inspector/memory_inspector/frontends/www_content/js/settings.js
@@ -0,0 +1,90 @@
+// Copyright 2014 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.
+
+settings = new (function() {
+
+this.onDomReady_ = function() {
+ $('#settings-load').click(this.reload.bind(this));
+ $('#settings-store').click(this.store.bind(this));
+};
+
+this.reload = function() {
+ $('#settings-container').empty();
+
+ // Query the backend-specific settings (e.g., adb path).
+ devices.getAllBackends().forEach(function(backend) {
+ webservice.ajaxRequest(
+ '/settings/' + backend,
+ this.onGetSettingsAjaxResponse_.bind(
+ this, 'backend ' + backend, backend));
+ }, this);
+
+ // Also query the device-specific settings (e.g., symbol path).
+ devices.getAllDevices().forEach(function(device) {
+ var deviceUri = device.backend + '/' + device.id;
+ var deviceTitle = 'device ' + device.name + ' [' + device.id + ']';
+ webservice.ajaxRequest(
+ '/settings/' + deviceUri,
+ this.onGetSettingsAjaxResponse_.bind(this, deviceTitle, deviceUri));
+ }, this);
+};
+
+this.store = function() {
+ var container = $('#settings-container');
+ var targetsSettings = {};
+
+ $('input[type="text"]', container).each(function(_, field) {
+ field = $(field);
+ var key = field.data('key');
+ var target = field.data('target');
+ var value = field.val();
+ if (!(target in targetsSettings))
+ targetsSettings[target] = {}
+ targetsSettings[target][key] = value
+ });
+
+ for (var target in targetsSettings) {
+ var targetsSetting = targetsSettings[target];
+ webservice.ajaxRequest('/settings/' + target,
+ this.onSetSettingsAjaxResponse_.bind(this, target),
+ this.onSetSettingsAjaxError_.bind(this),
+ targetsSetting);
+ }
+};
+
+this.onGetSettingsAjaxResponse_ = function(title, target, data) {
+ var container = $('#settings-container');
+ container.append($('<h2/>').text('Settings for ' + title));
+ var table = $('<table/>');
+ Object.keys(data).forEach(function(key) {
+ var setting = data[key];
+ var row = $('<tr/>');
+ var textfield = $('<input type="text"/>');
+ textfield.data('target', target);
+ textfield.data('key', key);
+ textfield.val(setting.value);
+ row.append($('<td/>').text(setting.description));
+ row.append($('<td/>').append(textfield));
+ table.append(row);
+ }, this);
+ container.append(table);
+};
+
+this.onSetSettingsAjaxResponse_ = function(target, data) {
+ var container = $('#settings-container');
+ $('input[type="text"]', container).each(function(_, field) {
+ field = $(field);
+ if (field.data('target') == target)
+ field.addClass('saved');
+ });
+};
+
+this.onSetSettingsAjaxError_ = function(httpStatus, errorMsg) {
+ rootUi.showDialog(
+ 'Error ' + httpStatus + ' while storing settings: ' + errorMsg);
+};
+
+$(document).ready(this.onDomReady_.bind(this));
+
+})(); \ No newline at end of file
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_content/settings.css b/tools/memory_inspector/memory_inspector/frontends/www_content/settings.css
new file mode 100644
index 0000000..cb3d90d
--- /dev/null
+++ b/tools/memory_inspector/memory_inspector/frontends/www_content/settings.css
@@ -0,0 +1,25 @@
+/* Copyright 2014 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. */
+
+#tabs-settings table {
+ width: 100%
+}
+
+#tabs-settings table td {
+ padding: 0.2em;
+}
+
+#tabs-settings table td:last-of-type {
+ width: 70%;
+}
+
+#tabs-settings input[type="text"] {
+ width: 100%;
+ font-family: monospace;
+ font-size: 0.8em;
+}
+
+#tabs-settings input[type="text"].saved {
+ background: #ded;
+} \ No newline at end of file
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_server.py b/tools/memory_inspector/memory_inspector/frontends/www_server.py
index 3ba68e9..fdf605d 100644
--- a/tools/memory_inspector/memory_inspector/frontends/www_server.py
+++ b/tools/memory_inspector/memory_inspector/frontends/www_server.py
@@ -109,6 +109,11 @@ def _ListBackends(args, req_vars): # pylint: disable=W0613
def _ListDevices(args, req_vars): # pylint: disable=W0613
resp = []
for device in backends.ListDevices():
+ # The device settings must loaded at discovery time (i.e. here), not during
+ # startup, because it might have been plugged later.
+ for k, v in _persistent_storage.LoadSettings(device.id).iteritems():
+ device.settings[k] = v
+
resp += [{'backend': device.backend.name,
'id': device.id,
'name': device.name}]
@@ -254,6 +259,48 @@ def _GetProcessStats(args, req_vars): # pylint: disable=W0613
return _HTTP_OK, [], {'cpu': cpu_stats, 'mem': mem_stats}
+@AjaxHandler(r'/ajax/settings/(\w+)/?(\w+)?$') # /ajax/settings/Android[/id]
+def _GetDeviceOrBackendSettings(args, req_vars): # pylint: disable=W0613
+ backend = backends.GetBackend(args[0])
+ if not backend:
+ return _HTTP_GONE, [], 'Backend not found'
+ if args[1]:
+ device = _GetDevice(args)
+ if not device:
+ return _HTTP_GONE, [], 'Device not found'
+ settings = device.settings
+ else:
+ settings = backend.settings
+
+ assert(isinstance(settings, backends.Settings))
+ resp = {}
+ for key in settings.expected_keys:
+ resp[key] = {'description': settings.expected_keys[key],
+ 'value': settings.values[key]}
+ return _HTTP_OK, [], resp
+
+
+@AjaxHandler(r'/ajax/settings/(\w+)/?(\w+)?$', 'POST')
+def _SetDeviceOrBackendSettings(args, req_vars): # pylint: disable=W0613
+ backend = backends.GetBackend(args[0])
+ if not backend:
+ return _HTTP_GONE, [], 'Backend not found'
+ if args[1]:
+ device = _GetDevice(args)
+ if not device:
+ return _HTTP_GONE, [], 'Device not found'
+ settings = device.settings
+ storage_name = device.id
+ else:
+ settings = backend.settings
+ storage_name = backend.name
+
+ for key in req_vars.iterkeys():
+ settings[key] = req_vars[key]
+ _persistent_storage.StoreSettings(storage_name, settings.values)
+ return _HTTP_OK, [], ''
+
+
@UriHandler(r'^(?!/ajax)/(.*)$')
def _StaticContent(args, req_vars): # pylint: disable=W0613
# Give the browser a 1-day TTL cache to minimize the start-up time.
@@ -307,5 +354,11 @@ def _HttpRequestHandler(environ, start_response):
def Start(http_port):
+ # Load the saved backends' settings (some of them might be needed to bootstrap
+ # as, for instance, the adb path for the Android backend).
+ for backend in backends.ListBackends():
+ for k, v in _persistent_storage.LoadSettings(backend.name).iteritems():
+ backend.settings[k] = v
+
httpd = wsgiref.simple_server.make_server('', http_port, _HttpRequestHandler)
httpd.serve_forever() \ No newline at end of file