diff options
author | primiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 15:18:16 +0000 |
---|---|---|
committer | primiano@chromium.org <primiano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 15:18:16 +0000 |
commit | c2d2ef92677c79d67d637e5bb613f059c5aca18b (patch) | |
tree | b9dc237638718f13d8798f8e31f922583fc7ddbb /tools/memory_inspector | |
parent | 990636841d4924f06103e0fb1d102791efe969d6 (diff) | |
download | chromium_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')
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 |