Commit dc5cefc1 authored by tengs's avatar tengs Committed by Commit bot

Hook up PA_LOG() logs to chrome://proximity-auth WebUI.

BUG=409158
TEST=manual

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

Cr-Commit-Position: refs/heads/master@{#329877}
parent 2b496b6d
...@@ -37,16 +37,26 @@ LogBuffer* LogBuffer::GetInstance() { ...@@ -37,16 +37,26 @@ LogBuffer* LogBuffer::GetInstance() {
return &g_log_buffer.Get(); return &g_log_buffer.Get();
} }
void LogBuffer::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void LogBuffer::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void LogBuffer::AddLogMessage(const LogMessage& log_message) { void LogBuffer::AddLogMessage(const LogMessage& log_message) {
// Note: We may want to sort the messages by timestamp if there are cases // Note: We may want to sort the messages by timestamp if there are cases
// where logs are not added chronologically. // where logs are not added chronologically.
log_messages_.push_back(log_message); log_messages_.push_back(log_message);
if (log_messages_.size() > MaxBufferSize()) if (log_messages_.size() > MaxBufferSize())
log_messages_.pop_front(); log_messages_.pop_front();
FOR_EACH_OBSERVER(Observer, observers_, OnLogMessageAdded(log_message));
} }
void LogBuffer::Clear() { void LogBuffer::Clear() {
log_messages_.clear(); log_messages_.clear();
FOR_EACH_OBSERVER(Observer, observers_, OnLogBufferCleared());
} }
size_t LogBuffer::MaxBufferSize() const { size_t LogBuffer::MaxBufferSize() const {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h"
#include "base/time/time.h" #include "base/time/time.h"
namespace proximity_auth { namespace proximity_auth {
...@@ -33,12 +34,25 @@ class LogBuffer { ...@@ -33,12 +34,25 @@ class LogBuffer {
logging::LogSeverity severity); logging::LogSeverity severity);
}; };
class Observer {
public:
// Called when a new message is added to the log buffer.
virtual void OnLogMessageAdded(const LogMessage& log_message) = 0;
// Called when all messages in the log buffer are cleared.
virtual void OnLogBufferCleared() = 0;
};
LogBuffer(); LogBuffer();
~LogBuffer(); ~LogBuffer();
// Returns the global instance. // Returns the global instance.
static LogBuffer* GetInstance(); static LogBuffer* GetInstance();
// Adds and removes log buffer observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Adds a new log message to the buffer. If the number of log messages exceeds // Adds a new log message to the buffer. If the number of log messages exceeds
// the maximum, then the earliest added log will be removed. // the maximum, then the earliest added log will be removed.
void AddLogMessage(const LogMessage& log_message); void AddLogMessage(const LogMessage& log_message);
...@@ -56,6 +70,9 @@ class LogBuffer { ...@@ -56,6 +70,9 @@ class LogBuffer {
// The messages currently in the buffer. // The messages currently in the buffer.
std::list<LogMessage> log_messages_; std::list<LogMessage> log_messages_;
// List of observers.
ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(LogBuffer); DISALLOW_COPY_AND_ASSIGN(LogBuffer);
}; };
......
...@@ -33,6 +33,9 @@ ProximityAuthUI::ProximityAuthUI(content::WebUI* web_ui) ...@@ -33,6 +33,9 @@ ProximityAuthUI::ProximityAuthUI(content::WebUI* web_ui)
source->AddResourcePath("device-list.html", source->AddResourcePath("device-list.html",
IDR_PROXIMITY_AUTH_DEVICE_LIST_HTML); IDR_PROXIMITY_AUTH_DEVICE_LIST_HTML);
source->AddResourcePath("device-list.js", IDR_PROXIMITY_AUTH_DEVICE_LIST_JS); source->AddResourcePath("device-list.js", IDR_PROXIMITY_AUTH_DEVICE_LIST_JS);
source->AddResourcePath("log-buffer.html",
IDR_PROXIMITY_AUTH_LOG_BUFFER_HTML);
source->AddResourcePath("log-buffer.js", IDR_PROXIMITY_AUTH_LOG_BUFFER_JS);
content::BrowserContext* browser_context = content::BrowserContext* browser_context =
web_ui->GetWebContents()->GetBrowserContext(); web_ui->GetWebContents()->GetBrowserContext();
......
...@@ -4,15 +4,85 @@ ...@@ -4,15 +4,85 @@
#include "components/proximity_auth/webui/proximity_auth_webui_handler.h" #include "components/proximity_auth/webui/proximity_auth_webui_handler.h"
#include "base/bind.h"
#include "base/i18n/time_formatting.h"
#include "base/values.h"
#include "content/public/browser/web_ui.h"
namespace proximity_auth { namespace proximity_auth {
namespace {
// Keys in the JSON representation of a log message.
const char kLogMessageTextKey[] = "text";
const char kLogMessageTimeKey[] = "time";
const char kLogMessageFileKey[] = "file";
const char kLogMessageLineKey[] = "line";
const char kLogMessageSeverityKey[] = "severity";
// Converts |log_message| to a raw dictionary value used as a JSON argument to
// JavaScript functions.
scoped_ptr<base::DictionaryValue> LogMessageToDictionary(
const LogBuffer::LogMessage& log_message) {
scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
dictionary->SetString(kLogMessageTextKey, log_message.text);
dictionary->SetString(kLogMessageTimeKey,
base::TimeFormatTimeOfDay(log_message.time));
dictionary->SetString(kLogMessageFileKey, log_message.file);
dictionary->SetInteger(kLogMessageLineKey, log_message.line);
dictionary->SetInteger(kLogMessageSeverityKey,
static_cast<int>(log_message.severity));
return dictionary.Pass();
}
} // namespace
ProximityAuthWebUIHandler::ProximityAuthWebUIHandler() { ProximityAuthWebUIHandler::ProximityAuthWebUIHandler() {
LogBuffer::GetInstance()->AddObserver(this);
} }
ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() { ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() {
LogBuffer::GetInstance()->RemoveObserver(this);
} }
void ProximityAuthWebUIHandler::RegisterMessages() { void ProximityAuthWebUIHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"clearLogBuffer", base::Bind(&ProximityAuthWebUIHandler::ClearLogBuffer,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getLogMessages", base::Bind(&ProximityAuthWebUIHandler::GetLogMessages,
base::Unretained(this)));
}
void ProximityAuthWebUIHandler::OnLogMessageAdded(
const LogBuffer::LogMessage& log_message) {
scoped_ptr<base::DictionaryValue> dictionary =
LogMessageToDictionary(log_message);
web_ui()->CallJavascriptFunction("LogBufferInterface.onLogMessageAdded",
*dictionary);
}
void ProximityAuthWebUIHandler::OnLogBufferCleared() {
web_ui()->CallJavascriptFunction("LogBufferInterface.onLogBufferCleared");
}
void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) {
base::ListValue json_logs;
auto logs = LogBuffer::GetInstance()->logs();
std::transform(logs->begin(), logs->end(), json_logs.begin(),
[](const LogBuffer::LogMessage& log) {
return LogMessageToDictionary(log).release();
});
web_ui()->CallJavascriptFunction("LogBufferInterface.onGotLogMessages",
json_logs);
}
void ProximityAuthWebUIHandler::ClearLogBuffer(const base::ListValue* args) {
// The OnLogBufferCleared() observer function will be called after the buffer
// is cleared.
LogBuffer::GetInstance()->Clear();
} }
} // namespace proximity_auth } // namespace proximity_auth
...@@ -5,22 +5,36 @@ ...@@ -5,22 +5,36 @@
#ifndef COMPONENTS_PROXIMITY_AUTH_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_ #ifndef COMPONENTS_PROXIMITY_AUTH_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_
#define COMPONENTS_PROXIMITY_AUTH_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_ #define COMPONENTS_PROXIMITY_AUTH_WEBUI_PROXIMITY_AUTH_WEBUI_HANDLER_H_
#include "components/proximity_auth/logging/log_buffer.h"
#include "content/public/browser/web_ui_message_handler.h" #include "content/public/browser/web_ui_message_handler.h"
namespace base {
class ListValue;
}
namespace proximity_auth { namespace proximity_auth {
class ProximityAuthService; class ProximityAuthService;
// Handles messages from the chrome://proximity-auth page. // Handles messages from the chrome://proximity-auth page.
class ProximityAuthWebUIHandler : public content::WebUIMessageHandler { class ProximityAuthWebUIHandler : public content::WebUIMessageHandler,
public LogBuffer::Observer {
public: public:
ProximityAuthWebUIHandler(); ProximityAuthWebUIHandler();
~ProximityAuthWebUIHandler() override; ~ProximityAuthWebUIHandler() override;
// content::WebUIMessageHandler implementation. // content::WebUIMessageHandler:
void RegisterMessages() override; void RegisterMessages() override;
private: private:
// LogBuffer::Observer:
void OnLogMessageAdded(const LogBuffer::LogMessage& log_message) override;
void OnLogBufferCleared() override;
// Message handler callbacks.
void GetLogMessages(const base::ListValue* args);
void ClearLogBuffer(const base::ListValue* args);
DISALLOW_COPY_AND_ASSIGN(ProximityAuthWebUIHandler); DISALLOW_COPY_AND_ASSIGN(ProximityAuthWebUIHandler);
}; };
......
<link href="chrome://resources/polymer/polymer/polymer.html" rel="import">
<polymer-element name="log-buffer">
<template></template>
<script src="log-buffer.js"></script>
</polymer-element>
// Copyright 2015 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.
Polymer('log-buffer', {
publish: {
/**
* List of displayed logs.
* @type {?Array.<{{
* text: string,
* time: string,
* file: string,
* line: number,
* severity: number,
* }}>} LogMessage
*/
logs: null,
},
/**
* Called when an instance is created.
*/
created: function() {
this.logs = [];
// We assume that only one instance of log-buffer is ever created.
LogBufferInterface = this;
chrome.send('getLogMessages');
},
// Clears the native LogBuffer.
clearLogs: function() {
chrome.send('clearLogBuffer');
},
// Handles when a new log message is added.
onLogMessageAdded: function(log) {
this.logs.push(log);
},
// Handles when the logs are cleared.
onLogBufferCleared: function() {
this.logs = [];
},
// Handles when the logs are returned in response to the 'getLogMessages'
// request.
onGotLogMessages: function(logs) {
this.logs = logs;
}
});
// Interface with the native WebUI component for LogBuffer events. The functions
// contained in this object will be invoked by the browser for each operation
// performed on the native LogBuffer.
LogBufferInterface = {
/**
* Called when a new log message is added.
* @type {function(LogMessage)}
*/
onLogMessageAdded: function(log) {},
/**
* Called when the log buffer is cleared.
* @type {function()}
*/
onLogBufferCleared: function() {},
/**
* Called in response to chrome.send('getLogMessages') with the log messages
* currently in the buffer.
* @type {function(Array.<LogMessage>)}
*/
onGotLogMessages: function(messages) {},
};
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<link href="chrome://resources/polymer/core-toolbar/core-toolbar.html" rel="import"> <link href="chrome://resources/polymer/core-toolbar/core-toolbar.html" rel="import">
<link href="chrome://resources/polymer/paper-icon-button/paper-icon-button.html" rel="import"> <link href="chrome://resources/polymer/paper-icon-button/paper-icon-button.html" rel="import">
<link href="chrome://resources/polymer/core-icons/communication-icons.html" rel="import"> <link href="chrome://resources/polymer/core-icons/communication-icons.html" rel="import">
<link href="log-buffer.html" rel="import">
<polymer-element name="log-panel" layout vertical> <polymer-element name="log-panel" layout vertical>
<template> <template>
...@@ -28,8 +29,18 @@ ...@@ -28,8 +29,18 @@
padding: 15px 30px; padding: 15px 30px;
} }
.list-item[severity="1"] {
background-color: #fffcef;
color: #312200;
}
.list-item[severity="2"] {
background-color: #fff1f1;
color: #ef0000;
}
.item-metadata { .item-metadata {
color: rgb(153, 153, 153); color: #888888;
font-size: 10px; font-size: 10px;
} }
...@@ -45,18 +56,19 @@ ...@@ -45,18 +56,19 @@
</style> </style>
<core-toolbar layout horizontal end-justified center <core-toolbar layout horizontal end-justified center
on-click="{{clearLogs}}"> on-click="{{clearLogs_}}">
<paper-icon-button icon="communication:clear-all"></paper-icon-button> <paper-icon-button icon="communication:clear-all"></paper-icon-button>
</core-toolbar> </core-toolbar>
<log-buffer id='logBuffer' logs="{{logs}}"></log-buffer>
<div id="list" flex> <div id="list" flex>
<template repeat="{{log in logs}}"> <template repeat="{{log in logs}}">
<div class="list-item {{ {selected: log.selected} | tokenList }}" <div class="list-item {{ {selected: log.selected} | tokenList }}"
on-click={{itemClick}}> on-click={{itemClick}} severity="{{log.severity}}">
<div class="item-metadata" layout horizontal> <div class="item-metadata" layout horizontal>
<div>14:23:50</div> <div>{{log.time}}</div>
<div flex></div> <div flex></div>
<div>proximity_auth_class.cc:123</div> <div>{{stripPath_(log.file)}}:{{log.line}}</div>
</div> </div>
<pre class="item-log" flex>{{log.text}}</pre> <pre class="item-log" flex>{{log.text}}</pre>
</div> </div>
......
...@@ -16,202 +16,24 @@ Polymer('log-panel', { ...@@ -16,202 +16,24 @@ Polymer('log-panel', {
}, },
/** /**
* Called when an instance is created. * @type {boolean}
*/
created: function() {
this.logs = [
{ text: 'sh: missing ]' },
{ text: 'Starting Mount filesystems on boot [ OK ]' },
{ text: 'Starting Populate /dev filesystem [ OK ]' },
{ text: 'Stopping Populate /dev filesystem [ OK ]' },
{ text: 'Starting Create /var/run/ccache [ OK ]' },
{ text: 'Starting Populate and link to /run filesystem [ OK ]' },
{ text: 'Starting Create /run/credentials-cache [ OK ]' },
{ text: 'Stopping Create /var/run/ccache [ OK ]' },
{ text: 'Stopping Populate and link to /run filesystem [ OK ]' },
{ text: 'Stopping Create /run/credentials-cache [ OK ]' },
{ text: 'Starting Signal sysvinit that the rootfs is mounted [ OK ]' },
{ text: 'Starting Clean /tmp directory [ OK ]' },
{ text: 'Stopping Track if upstart is running in a container [ OK ]' },
{ text: 'Starting mount available cgroup filesystems [ OK ]' },
{ text: 'Stopping Clean /tmp directory [ OK ]' },
{ text: 'Starting Initialize or finalize resolvconf [ OK ]' },
{ text: 'mount: none already mounted or /dev/cgroup/cpu busy' },
{ text: 'Starting Set custom IMA policy [ OK ]' },
{ text: 'Stopping Set custom IMA policy [ OK ]' },
{ text: 'Starting Bridge udev events into upstart [ OK ]' },
{ text: 'Starting detecthammer security monitoring daemon [ OK ]' },
{ text: 'Starting linhelm security monitoring daemon [ OK ]' },
{ text: 'Starting Fetch otp over bluetooth on demand [ OK ]' },
{ text: 'Starting device node and kernel event manager [ OK ]' },
{ text: 'Starting Enabling additional executable binary formats [ OK ]' },
{ text: 'Starting flush early job output to logs [ OK ]' },
{ text: 'Stopping Mount filesystems on boot [ OK ]' },
{ text: 'Starting NFSv4 id <-> name mapper [ OK ]' },
{ text: 'Stopping flush early job output to logs [ OK ]' },
{ text: 'Starting load modules from /etc/modules [ OK ]' },
{ text: 'Starting load modules from /etc/modules [ OK ]' },
{ text: 'Starting log initial device creation [ OK ]' },
{ text: 'Starting D-Bus system message bus [ OK ]' },
{ text: 'Stopping load modules from /etc/modules [ OK ]' },
{ text: 'Stopping load modules from /etc/modules [ OK ]' },
{ text: 'Starting Uncomplicated firewall [ OK ]' },
{ text: 'Starting Bridge file events into upstart [ OK ]' },
{ text: 'Starting bluetooth daemon [ OK ]' },
{ text: 'Starting SystemD login management service [ OK ]' },
{ text: 'Starting system logging daemon [ OK ]' },
{ text: 'Starting configure network device security [ OK ]' },
{ text: 'Starting configure network device security [ OK ]' },
{ text: 'Stopping cold plug devices [ OK ]' },
{ text: 'Starting configure network device security [ OK ]' },
{ text: 'Starting CUPS printing spooler/server [ OK ]' },
{ text: 'Starting configure network device [ OK ]' },
{ text: 'Starting Mount network filesystems [ OK ]' },
{ text: 'Starting Upstart job to start rpcbind on boot only [ OK ]' },
{ text: 'Starting Failsafe Boot Delay [ OK ]' },
{ text: 'Stopping log initial device creation [ OK ]' },
{ text: 'Stopping Upstart job to start rpcbind on boot only [ OK ]' },
{ text: 'Starting load fallback graphics devices [ OK ]' },
{ text: 'Starting configure network device security [ OK ]' },
{ text: 'Starting configure network device [ OK ]' },
{ text: 'Stopping load fallback graphics devices [ OK ]' },
{ text: 'Stopping Failsafe Boot Delay [ OK ]' },
{ text: 'Stopping Mount network filesystems [ OK ]' },
{ text: 'Starting System V initialisation compatibility [ OK ]' },
{ text: 'Starting configure virtual network devices [ OK ]' },
{ text: 'Initializing random number generator... [ OK ]' },
{ text: 'Setting up X socket directories... [ OK ]' },
{ text: 'Starting configure network device [ OK ]' },
{ text: 'Starting modem connection manager [ OK ]' },
{ text: 'Starting configure network device security [ OK ]' },
{ text: 'Starting RPC portmapper replacement [ OK ]' },
{ text: 'Stopping System V initialisation compatibility [ OK ]' },
{ text: 'Starting Create /var/run/ccache [ OK ]' },
{ text: 'Stopping Create /var/run/ccache [ OK ]' },
{ text: 'Starting Monitor for unauthorized access to cookies. [ OK ]' },
{ text: 'Starting System V runlevel compatibility [ OK ]' },
{ text: 'Starting anac(h)ronistic cron [ OK ]' },
{ text: 'Starting ACPI daemon [ OK ]' },
{ text: 'Starting regular background program processing daemon [ OK ]' },
{ text: 'Starting deferred execution scheduler [ OK ]' },
{ text: 'Starting Run the nvidia-updater Upstart task before the ' +
'goobuntu-updater Upstart task [ OK ]' },
{ text: 'Starting build kernel modules for current kernel [ OK ]' },
{ text: 'Starting CPU interrupts balancing daemon [ OK ]' },
{ text: 'Starting rpcsec_gss daemon [ OK ]' },
{ text: 'Starting NSM status monitor [ OK ]' },
{ text: 'Stopping anac(h)ronistic cron [ OK ]' },
{ text: 'Starting Run the nvidia-updater during startup [ OK ]' },
{ text: 'Starting regular background program processing daemon [ OK ]' },
{ text: 'Starting KVM [ OK ]' },
{ text: 'Starting automatic crash report generation [ OK ]' },
{ text: 'Starting Automounter [ OK ]' },
{ text: 'Stopping Restore Sound Card State [ OK ]' },
{ text: 'Starting libvirt daemon [ OK ]' },
{ text: 'gdm start/starting' },
{ text: 'initctl: Unknown job: kdm' },
{ text: 'lightdm start/starting' },
{ text: 'initctl: Unknown job: lxdm' },
{ text: 'Starting Bridge socket events into upstart [ OK ]' },
{ text: 'Skipping profile in /etc/apparmor.d/disable: usr.bin.firefox' },
{ text: 'Starting AppArmor profiles [ OK ]' },
{ text: 'Checking for available NVIDIA updates ...' },
{ text: 'Starting audit daemon auditd [ OK ]' },
{ text: 'Starting Dropbear SSH server: [abort] NO_START is not ' +
'set to zero in /etc/default/dropbear' },
{ text: 'Starting logs-exporterd [ OK ]' },
{ text: 'Starting Machine Check Exceptions decoder: mcelog.' },
{ text: 'ERROR: [Errno -2] Name or service not known' },
{ text: '2015-04-01 13:12:35,580:INFO:Daemon process started in the ' +
'background, logging to ' +
'"/tmp/chrome_remote_desktop_20150401_131235_3BiEyp"' },
{ text: 'Using host_id: cd1af87e-488c-38ec-6b84-40e028bbf174' },
{ text: 'Launching X server and X session.' },
{ text: 'Starting NTP server ntpd [ OK ]' },
{ text: 'Not starting internet superserver: no services enabled' },
{ text: 'Starting OpenCryptoki PKCS#11 slot daemon: pkcsslotd.' },
{ text: 'Starting OSS Proxy Daemon osspd [ OK ]' },
{ text: 'Starting /usr/bin/Xvfb-randr on display :20' },
{ text: 'Starting network connection manager [ OK ]' },
{ text: 'INFO: Configuring network-manager from upstart' },
{ text: '/proc/self/fd/9: line 6: INFO: Configuring network-manager ' +
'from upstart: command not found' },
{ text: 'Updating connection SNAX' },
{ text: 'Xvfb is active.' },
{ text: 'Completed successfully' },
{ text: 'INFO: Success' },
{ text: '/proc/self/fd/9: line 6: INFO: Success: command not found' },
{ text: 'Starting Postfix Mail Transport Agent postfix [ OK ]' },
{ text: 'Stopping build kernel modules for current kernel [ OK ]' },
{ text: 'Launching host process' },
{ text: 'Stopping Run the nvidia-updater during startup [ OK ]' },
{ text: 'Stopping Run the nvidia-updater Upstart task before the ' +
'goobuntu-updater Upstart task [ OK ]' },
{ text: 'Waiting up to 60s for the hostname ...' },
{ text: 'Recovering schroot sessions [ OK ]' },
{ text: '[33m*39;49m Not starting S.M.A.R.T. daemon smartd, disabled ' +
'via /etc/default/smartmontools' },
{ text: 'Starting OpenBSD Secure Shell server... [ OK ]' },
{ text: 'No response from daemon. It may have crashed, or may still ' +
'be running in the background.' },
{ text: 'Host ready to receive connections.' },
{ text: 'Log file: /tmp/chrome_remote_desktop_20150401_131235_3BiEyp' },
{ text: 'Starting VirtualBox kernel modules [ OK ]' },
{ text: 'saned disabled; edit /etc/default/saned' },
{ text: 'Restoring resolver state... [ OK ]' },
{ text: 'The hostname has not changed' },
{ text:
'access-control-allow-origin:*\n ' +
'cache-control:public, max-age=600\n ' +
'date:Thu, 16 Apr 2015 21:15:23 GMT\n ' +
'etag:"nhb8IQ"\n ' +
'expires:Thu, 16 Apr 2015 21:25:23 GMT\n ' +
'server:Google Frontend\n ' +
'status:304\n ' +
'x-google-appengine-appid:s~polymer-project\n ' +
'x-google-appengine-module:default\n ' +
'x-google-appengine-version:2015-04-13\n ' +
'x-google-backends:/gns/project/apphosting/appserver/prod-appengine' +
'/ic/prod-appengine.remote-ib.appserver/380,icbie6.prod.google.com:' +
'4489,/bns/ic/borg/ic/bns/apphosting/prod-appengine.edge.frontend/2' +
'30,ibk19:6599,/bns/ib/borg/ib/bns/gfe-prod/shared-gfe_31_silos/1.g' +
'fe,icna18:9845\n ' +
'x-google-dos-service-trace:main:apphosting,dasher:' +
'apphosting\n ' +
'x-google-gfe-request-trace:icna18:9845,ibk19:6599,/bns/ic/borg/ic/' +
'bns/apphosting/prod-appengine.edge.frontend/230,ibk19:6599,icna18:' +
'9845\n ' +
'x-google-gfe-response-code-details-trace:response_code_set_by_back' +
'end,response_code_set_by_backend\n ' +
'x-google-gfe-service-trace:apphosting,dasher_zoo_responder,apphost' +
'ing\n ' +
'x-google-gslb-service:apphosting\n ' +
'x-google-netmon-label:/bns/ic/borg/ic/bns/apphosting/prod-appengin' +
'e.edge.frontend/230\n ' +
'x-google-service:apphosting,apphosting\n' },
{ text: 'goobuntu-updater configuration: ARGS="--init ' +
'--only-if-forced --verbose" BLOCK_BOOT=false' },
{ text: 'Running goobuntu-updater ...' },
{ text: 'Starting GNOME Display Manager [ OK ]' },
{ text: 'No apache MPM package installed' },
{ text: 'Starting Unblock the restart of the gdm display ' +
'manager when it stops by emitting the ' +
'nvidia-updater-unblock-gdm-start event [ OK ]' },
{ text: 'Stopping GNOME Display Manager [ OK ]' },
];
},
/**
* Stores the logs that are cleared.
* @type {Array.<Log>}
* @private * @private
*/ */
prevLogs_: null, isScrollAtBottom_: true,
/** /**
* Called after the Polymer element is initialized. * Called after the Polymer element is initialized.
*/ */
ready: function() { ready: function() {
this.$.list.onscroll = this.onScroll_.bind(this);
this.async(this.scrollToBottom_);
},
/**
* Called when the list of logs change.
*/
logsChanged: function(oldValue, newValue) {
if (this.isScrollAtBottom_)
this.async(this.scrollToBottom_); this.async(this.scrollToBottom_);
}, },
...@@ -219,11 +41,18 @@ Polymer('log-panel', { ...@@ -219,11 +41,18 @@ Polymer('log-panel', {
* Clears the logs. * Clears the logs.
* @private * @private
*/ */
clearLogs: function() { clearLogs_: function() {
var prevLogs = this.logs; this.$.logBuffer.clearLogs();
this.logs = this.prevLogs; },
this.prevLogs = prevLogs;
this.async(this.scrollToBottom_); /**
* Event handler when the list is scrolled.
* @private
*/
onScroll_: function() {
var list = this.$.list;
this.isScrollAtBottom_ =
list.scrollTop + list.offsetHeight == list.scrollHeight;
}, },
/** /**
...@@ -233,4 +62,14 @@ Polymer('log-panel', { ...@@ -233,4 +62,14 @@ Polymer('log-panel', {
scrollToBottom_: function() { scrollToBottom_: function() {
this.$.list.scrollTop = this.$.list.scrollHeight; this.$.list.scrollTop = this.$.list.scrollHeight;
}, },
/**
* @param {string} filename
* @return {string} The filename stripped of its preceeding path.
* @private
*/
stripPath_: function(filename) {
var directories = filename.split('/');
return directories[directories.length - 1];
},
}); });
...@@ -18,4 +18,8 @@ ...@@ -18,4 +18,8 @@
file="../proximity_auth/webui/resources/device-list.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> file="../proximity_auth/webui/resources/device-list.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROXIMITY_AUTH_DEVICE_LIST_JS" <include name="IDR_PROXIMITY_AUTH_DEVICE_LIST_JS"
file="../proximity_auth/webui/resources/device-list.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> file="../proximity_auth/webui/resources/device-list.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROXIMITY_AUTH_LOG_BUFFER_HTML"
file="../proximity_auth/webui/resources/log-buffer.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROXIMITY_AUTH_LOG_BUFFER_JS"
file="../proximity_auth/webui/resources/log-buffer.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
</grit-part> </grit-part>
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