summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-25 21:37:52 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-25 21:37:52 +0000
commit76209c71720e450ddf810abc2220e4419f8754fb (patch)
treea9226e45f5119e336f1e3d7b5c8ce1e04c1edec5
parenta2fffa415022480e1ad078f98da7e11e96ee396c (diff)
downloadchromium_src-76209c71720e450ddf810abc2220e4419f8754fb.zip
chromium_src-76209c71720e450ddf810abc2220e4419f8754fb.tar.gz
chromium_src-76209c71720e450ddf810abc2220e4419f8754fb.tar.bz2
sync: Display protocol events on about:sync
Displays a log of messages sent between sync client and server on the main about:sync page. Currently it does not save any events received while the about:sync page is closed, so there is no historical information. This feature will be added later. Adds the protocol events to the events tab, too. This allows protocol events to be dumped to text along with the rest of the event log. Removes the yellow fade effect from the main about:sync page. The fade was useful as an indicator that sync activity was in progress. Now that we can see the log of sync events growing, there's not much need for it anymore. Refactors the columns display on the main about:sync page. The new layout uses narrower columns, which should make it a bit more mobile-friendly. It also allows us to display more information, which is useful since that page is starting to get crowded. Fixes some style violations in the HTML and CSS for the about page. The new presubmit scripts would not let us modify this file until those style violations were fixed. This new information display should be a superset of what's already available. Adding it to the main page will make many of the indicators on the about tab redundant. This change is a step towards removing the indicators that rely on obsolete code paths. BUG=349301 Review URL: https://codereview.chromium.org/210233005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259344 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/sync_internals/about.css95
-rw-r--r--chrome/browser/resources/sync_internals/about.html21
-rw-r--r--chrome/browser/resources/sync_internals/about.js193
-rw-r--r--chrome/browser/resources/sync_internals/sync_log.js4
-rw-r--r--chrome/browser/ui/webui/DEPS1
-rw-r--r--chrome/browser/ui/webui/sync_internals_message_handler.cc23
-rw-r--r--chrome/browser/ui/webui/sync_internals_message_handler.h10
7 files changed, 219 insertions, 128 deletions
diff --git a/chrome/browser/resources/sync_internals/about.css b/chrome/browser/resources/sync_internals/about.css
index b530cc6..29a2a62 100644
--- a/chrome/browser/resources/sync_internals/about.css
+++ b/chrome/browser/resources/sync_internals/about.css
@@ -3,33 +3,36 @@
* found in the LICENSE file.
*/
-#aboutInfo {
- -webkit-columns: 3;
+#about-info {
+ -webkit-column-width: 350px;
}
-#aboutInfo h2 {
+#about-info > div {
+ -webkit-column-break-inside: avoid;
+ width: 350px;
+}
+
+#about-info h2 {
color: rgb(74, 142, 230);
font-size: 100%;
margin-bottom: 0;
}
-#aboutInfo .err {
+#about-info .err {
color: red;
}
-#aboutInfo .section {
- -webkit-column-break-inside: avoid;
+#about-info .section {
display: inline-block;
margin-left: auto;
margin-right: auto;
- width: 100%;
}
-.aboutDetails {
+.about-details {
width: 100%;
}
-.aboutDetails tr:nth-child(odd) {
+.about-details tr:nth-child(odd) {
background: rgb(239, 243, 255);
}
@@ -45,43 +48,59 @@
background: rgb(204, 255, 204);
}
-@-webkit-keyframes highlight1 {
- 0% {
- background: rgb(255, 255, 0);
- }
- 100% {
- background: #fff;
- }
+.about-details .uninitialized {
+ color: #7f7f7f;
}
-@-webkit-keyframes highlight2 {
- 0% {
- background: rgb(155, 158, 166);
- }
- 100% {
- background: rgb(239, 243, 255);
- }
+#status {
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+ width: 300px;
}
-.aboutDetails [highlighted] {
- -webkit-animation-duration: 3s;
- -webkit-animation-name: highlight1;
- -webkit-animation-timing-function: linear;
+#traffic-event-container {
+ border: 1px solid;
+ height: 500px;
+ max-width: 500px;
+ overflow-y: auto;
}
-.aboutDetails [highlighted]:nth-child(odd) {
- -webkit-animation-duration: 3s;
- -webkit-animation-name: highlight2;
- -webkit-animation-timing-function: linear;
+.traffic-event-entry {
+ border: 2px outset;
+ padding: 0.5em;
}
-.aboutDetails .uninitialized {
- color: #7f7f7f;
+.traffic-event-entry:hover {
+ background-color: #eee;
}
-#status {
- margin-left: auto;
- margin-right: auto;
- text-align: center;
- width: 300px;
+.traffic-event-entry .time {
+ color: #222;
+ font-family: sans-serif;
+}
+
+.traffic-event-entry .type {
+ font-family: sans-serif;
+ font-weight: bold;
+ margin: 0.5em;
+ white-space: nowrap;
+}
+
+.traffic-event-entry .details {
+ margin: 0.5em;
+ overflow-x: auto;
+}
+
+.traffic-event-entry .proto {
+ display: none;
+}
+
+.traffic-event-entry-expanded .proto {
+ background-color: #fff;
+ border: 1px solid #222;
+ display: block;
+ max-height: 300px;
+ overflow-x: auto;
+ overflow-y: auto;
}
diff --git a/chrome/browser/resources/sync_internals/about.html b/chrome/browser/resources/sync_internals/about.html
index 766e1bc..4aa8e34 100644
--- a/chrome/browser/resources/sync_internals/about.html
+++ b/chrome/browser/resources/sync_internals/about.html
@@ -14,19 +14,32 @@
</div>
</div>
-<div id='aboutInfo'>
+<div id='about-info'>
<div class="section" jsselect="details">
<h2 jscontent="title"></h2>
- <table class="aboutDetails">
+ <table class="about-details">
<tr jsselect="data"
- jsvalues="class:$this.is_valid ? '' : 'uninitialized'"
- jseval='highlightIfChanged(this, this.children[1].innerText, stat_value)'>
+ jsvalues="class:$this.is_valid ? '' : 'uninitialized'">
<td class="detail" jscontent="stat_name" width=50%></td>
<td class="value" jscontent="stat_value" width=50%></td>
</tr>
</table>
</div>
+ <div id="traffic-event-container-wrapper" jsskip="true">
+ <h2>Sync Protocol Log</h2>
+ <div id="traffic-event-container">
+ <div class="traffic-event-entry"
+ jsselect="events"
+ jseval="chrome.sync.about_tab.addExpandListener(this)">
+ <span class="time" jscontent="(new Date(time)).toLocaleString()"></span>
+ <span class="type" jscontent="type"></span>
+ <pre class="details" jscontent="details"></pre>
+ <pre class="proto" jscontent="JSON.stringify(proto, null, 2)"></pre>
+ </div>
+ </div>
+ </div>
+
<div class="section" style="overflow-x: auto">
<h2>Type Info</h2>
<table id="typeInfo">
diff --git a/chrome/browser/resources/sync_internals/about.js b/chrome/browser/resources/sync_internals/about.js
index 59f2847..172e690 100644
--- a/chrome/browser/resources/sync_internals/about.js
+++ b/chrome/browser/resources/sync_internals/about.js
@@ -2,89 +2,124 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-function highlightIfChanged(node, oldVal, newVal) {
- function clearHighlight() {
- this.removeAttribute('highlighted');
+cr.define('chrome.sync.about_tab', function() {
+ // Contains the latest snapshot of sync about info.
+ chrome.sync.aboutInfo = {};
+
+ function refreshAboutInfo(aboutInfo) {
+ chrome.sync.aboutInfo = aboutInfo;
+ var aboutInfoDiv = $('about-info');
+ jstProcess(new JsEvalContext(aboutInfo), aboutInfoDiv);
+ }
+
+ function onAboutInfoUpdatedEvent(e) {
+ refreshAboutInfo(e.details);
+ }
+
+ /** Container for accumulated sync protocol events. */
+ var protocolEvents = [];
+
+ /**
+ * Callback for incoming protocol events.
+ * @param {Event} e The protocol event.
+ */
+ function onReceivedProtocolEvent(e) {
+ var details = e.details;
+ protocolEvents.push(details);
+
+ var context = new JsEvalContext({ events: protocolEvents });
+ jstProcess(context, $('traffic-event-container'));
+ }
+
+ /**
+ * Initializes state and callbacks for the protocol event log UI.
+ */
+ function initProtocolEventLog() {
+ chrome.sync.events.addEventListener(
+ 'onProtocolEvent', onReceivedProtocolEvent);
+
+ // Make the prototype jscontent element disappear.
+ jstProcess({}, $('traffic-event-container'));
+ }
+
+ /**
+ * Toggles the given traffic event entry div's "expanded" state.
+ * @param {HTMLElement} element the element to toggle.
+ */
+ function expandListener(element) {
+ element.target.classList.toggle('traffic-event-entry-expanded');
}
- var oldStr = oldVal.toString();
- var newStr = newVal.toString();
- if (oldStr != '' && oldStr != newStr) {
- // Note the addListener function does not end up creating duplicate
- // listeners. There can be only one listener per event at a time.
- // Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
- node.addEventListener('webkitAnimationEnd', clearHighlight, false);
- node.setAttribute('highlighted', '');
+ /**
+ * Attaches a listener to the given traffic event entry div.
+ * @param {HTMLElement} element the element to attach the listener to.
+ */
+ function addExpandListener(element) {
+ element.addEventListener('click', expandListener, false);
}
-}
-
-(function() {
-// Contains the latest snapshot of sync about info.
-chrome.sync.aboutInfo = {};
-
-function refreshAboutInfo(aboutInfo) {
- chrome.sync.aboutInfo = aboutInfo;
- var aboutInfoDiv = $('aboutInfo');
- jstProcess(new JsEvalContext(aboutInfo), aboutInfoDiv);
-}
-
-function onAboutInfoUpdatedEvent(e) {
- refreshAboutInfo(e.details);
-}
-
-function onLoad() {
- $('status-data').hidden = true;
-
- chrome.sync.events.addEventListener(
- 'onAboutInfoUpdated',
- onAboutInfoUpdatedEvent);
- chrome.sync.requestUpdatedAboutInfo();
-
- var dumpStatusButton = $('dump-status');
- dumpStatusButton.addEventListener('click', function(event) {
- var aboutInfo = chrome.sync.aboutInfo;
- if (!$('include-ids').checked) {
- aboutInfo.details = chrome.sync.aboutInfo.details.filter(function(el) {
- return !el.is_sensitive;
- });
- }
- var data = '';
- data += new Date().toString() + '\n';
- data += '======\n';
- data += 'Status\n';
- data += '======\n';
- data += JSON.stringify(aboutInfo, null, 2) + '\n';
-
- $('status-text').value = data;
- $('status-data').hidden = false;
- });
-
- var importStatusButton = $('import-status');
- importStatusButton.addEventListener('click', function(event) {
- $('status-data').hidden = false;
- if ($('status-text').value.length == 0) {
- $('status-text').value = 'Paste sync status dump here then click import.';
- return;
- }
-
- // First remove any characters before the '{'.
- var data = $('status-text').value;
- var firstBrace = data.indexOf('{');
- if (firstBrace < 0) {
- $('status-text').value = 'Invalid sync status dump.';
- return;
- }
- data = data.substr(firstBrace);
-
- // Remove listeners to prevent sync events from overwriting imported data.
- chrome.sync.events.removeEventListener(
+
+ function onLoad() {
+ $('status-data').hidden = true;
+
+ chrome.sync.events.addEventListener(
'onAboutInfoUpdated',
onAboutInfoUpdatedEvent);
+ chrome.sync.requestUpdatedAboutInfo();
+
+ var dumpStatusButton = $('dump-status');
+ dumpStatusButton.addEventListener('click', function(event) {
+ var aboutInfo = chrome.sync.aboutInfo;
+ if (!$('include-ids').checked) {
+ aboutInfo.details = chrome.sync.aboutInfo.details.filter(function(el) {
+ return !el.is_sensitive;
+ });
+ }
+ var data = '';
+ data += new Date().toString() + '\n';
+ data += '======\n';
+ data += 'Status\n';
+ data += '======\n';
+ data += JSON.stringify(aboutInfo, null, 2) + '\n';
+
+ $('status-text').value = data;
+ $('status-data').hidden = false;
+ });
+
+ var importStatusButton = $('import-status');
+ importStatusButton.addEventListener('click', function(event) {
+ $('status-data').hidden = false;
+ if ($('status-text').value.length == 0) {
+ $('status-text').value =
+ 'Paste sync status dump here then click import.';
+ return;
+ }
+
+ // First remove any characters before the '{'.
+ var data = $('status-text').value;
+ var firstBrace = data.indexOf('{');
+ if (firstBrace < 0) {
+ $('status-text').value = 'Invalid sync status dump.';
+ return;
+ }
+ data = data.substr(firstBrace);
+
+ // Remove listeners to prevent sync events from overwriting imported data.
+ chrome.sync.events.removeEventListener(
+ 'onAboutInfoUpdated',
+ onAboutInfoUpdatedEvent);
+
+ var aboutInfo = JSON.parse(data);
+ refreshAboutInfo(aboutInfo);
+ });
+
+ initProtocolEventLog();
+ }
- var aboutInfo = JSON.parse(data);
- refreshAboutInfo(aboutInfo);
- });
-}
+ return {
+ onLoad: onLoad,
+ addExpandListener: addExpandListener
+ };
+});
-document.addEventListener('DOMContentLoaded', onLoad, false);
-})();
+document.addEventListener(
+ 'DOMContentLoaded', chrome.sync.about_tab.onLoad, false);
diff --git a/chrome/browser/resources/sync_internals/sync_log.js b/chrome/browser/resources/sync_internals/sync_log.js
index 44d1f25..296a04a7 100644
--- a/chrome/browser/resources/sync_internals/sync_log.js
+++ b/chrome/browser/resources/sync_internals/sync_log.js
@@ -38,6 +38,10 @@ cr.define('chrome.sync', function() {
transaction: [
'onTransactionWrite',
],
+
+ protocol: [
+ 'onProtocolEvent',
+ ]
};
/**
diff --git a/chrome/browser/ui/webui/DEPS b/chrome/browser/ui/webui/DEPS
index f154c9a..7d9e166 100644
--- a/chrome/browser/ui/webui/DEPS
+++ b/chrome/browser/ui/webui/DEPS
@@ -4,6 +4,7 @@ include_rules = [
"+sync/js",
"+sync/internal_api/public/util/weak_handle.h",
+ "+sync/internal_api/public/events",
# Other libraries.
"+device/bluetooth",
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc
index 8a0ddd6..e0b64f9 100644
--- a/chrome/browser/ui/webui/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h"
+#include "sync/internal_api/public/events/protocol_event.h"
#include "sync/internal_api/public/util/weak_handle.h"
#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
@@ -24,12 +25,17 @@ using syncer::ModelTypeSet;
using syncer::WeakHandle;
SyncInternalsMessageHandler::SyncInternalsMessageHandler()
- : scoped_observer_(this),
- weak_ptr_factory_(this) {}
+ : weak_ptr_factory_(this) {}
SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
if (js_controller_)
js_controller_->RemoveJsEventHandler(this);
+
+ ProfileSyncService* service = GetProfileSyncService();
+ if (service && service->HasObserver(this)) {
+ service->RemoveObserver(this);
+ service->RemoveProtocolEventObserver(this);
+ }
}
void SyncInternalsMessageHandler::RegisterMessages() {
@@ -38,7 +44,8 @@ void SyncInternalsMessageHandler::RegisterMessages() {
// Register for ProfileSyncService events.
ProfileSyncService* service = GetProfileSyncService();
if (service) {
- scoped_observer_.Add(service);
+ service->AddObserver(this);
+ service->AddProtocolEventObserver(this);
js_controller_ = service->GetJsController();
js_controller_->AddJsEventHandler(this);
}
@@ -94,6 +101,16 @@ void SyncInternalsMessageHandler::OnStateChanged() {
SendAboutInfo();
}
+void SyncInternalsMessageHandler::OnProtocolEvent(
+ const syncer::ProtocolEvent& event) {
+ scoped_ptr<base::DictionaryValue> value(
+ syncer::ProtocolEvent::ToValue(event));
+ web_ui()->CallJavascriptFunction(
+ "chrome.sync.dispatchEvent",
+ base::StringValue("onProtocolEvent"),
+ *value);
+}
+
void SyncInternalsMessageHandler::HandleJsEvent(
const std::string& name,
const JsEventDetails& details) {
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.h b/chrome/browser/ui/webui/sync_internals_message_handler.h
index 902c1d6..806e25d 100644
--- a/chrome/browser/ui/webui/sync_internals_message_handler.h
+++ b/chrome/browser/ui/webui/sync_internals_message_handler.h
@@ -13,6 +13,7 @@
#include "base/scoped_observer.h"
#include "base/values.h"
#include "chrome/browser/sync/profile_sync_service_observer.h"
+#include "chrome/browser/sync/protocol_event_observer.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "sync/js/js_controller.h"
#include "sync/js/js_event_handler.h"
@@ -25,7 +26,8 @@ class SyncInternalsMessageHandler
: public content::WebUIMessageHandler,
public syncer::JsEventHandler,
public syncer::JsReplyHandler,
- public ProfileSyncServiceObserver {
+ public ProfileSyncServiceObserver,
+ public browser_sync::ProtocolEventObserver {
public:
SyncInternalsMessageHandler();
virtual ~SyncInternalsMessageHandler();
@@ -54,6 +56,9 @@ class SyncInternalsMessageHandler
// ProfileSyncServiceObserver implementation.
virtual void OnStateChanged() OVERRIDE;
+ // ProtocolEventObserver implementation.
+ virtual void OnProtocolEvent(const syncer::ProtocolEvent& e) OVERRIDE;
+
private:
// Helper function to register JsController function callbacks.
void RegisterJsControllerCallback(const std::string& name);
@@ -64,9 +69,6 @@ class SyncInternalsMessageHandler
ProfileSyncService* GetProfileSyncService();
- ScopedObserver<ProfileSyncService, SyncInternalsMessageHandler>
- scoped_observer_;
-
base::WeakPtr<syncer::JsController> js_controller_;
base::WeakPtrFactory<SyncInternalsMessageHandler> weak_ptr_factory_;